home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / tty32.zip / TTY.C < prev    next >
C/C++ Source or Header  |  1992-10-16  |  76KB  |  2,442 lines

  1. //---------------------------------------------------------------------------
  2. //
  3. //  Module: tty.c
  4. //
  5. //  Purpose:
  6. //     The sample application demonstrates the usage of the COMM
  7. //     API.  It implements the new COMM API of Windows 3.1.
  8. //
  9. //     NOTE:  no escape sequences are translated, only
  10. //            the necessary control codes (LF, CR, BS, etc.)
  11. //
  12. //  Description of functions:
  13. //     Descriptions are contained in the function headers.
  14. //
  15. //  Development Team:
  16. //     Bryan A. Woodruff
  17. //
  18. //  History:   Date       Author      Comment
  19. //
  20. //              5/ 8/91   BryanW      Wrote it.
  21. //
  22. //             10/18/91   BryanW      Sanitized code & comments.
  23. //
  24. //             10/22/91   BryanW      Minor bug fixes.
  25. //
  26. //             12/31/91   BryanW      Ported to Win32 (NT).
  27. //
  28. //              2/10/92   BryanW      Fixed a problem with ReadCommBlock()
  29. //                                    and error detection.  ReadComm() is
  30. //                                    now performed... if the result is < 0
  31. //                                    the error status is read using
  32. //                                    GetCommError() and displayed.  The
  33. //                                    length is adjusted (*= -1).
  34. //
  35. //              2/13/92   BryanW      Updated to provide the option to
  36. //                                    implement/handle CN_RECEIVE
  37. //                                    notifications.
  38. //
  39. //              2/13/92   BryanW      Implemented forced DTR control. DTR
  40. //                                    is asserted on connect and dropped
  41. //                                    on disconnect.
  42. //
  43. //              2/21/92   BryanW      Removed overhead of local memory
  44. //                                    functions - now uses LPTR for
  45. //                                    allocation from heap.
  46. //
  47. //              2/26/92   BryanW      Fixed off by one problem in paint
  48. //                                    calculations.
  49. //
  50. //              6/15/92   BryanW      Ported the "updated" version of TTY
  51. //                                    for Win 3.1 including bug fixes.
  52. //
  53. //---------------------------------------------------------------------------
  54. //
  55. //  Written by Microsoft Product Support Services, Windows Developer Support.
  56. //  Copyright (c) 1991 Microsoft Corporation.  All Rights Reserved.
  57. //
  58. //---------------------------------------------------------------------------
  59.  
  60. #include "tty.h"
  61.  
  62. //---------------------------------------------------------------------------
  63. //  int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
  64. //                      LPSTR lpszCmdLine, int nCmdShow )
  65. //
  66. //  Description:
  67. //     This is the main window loop!
  68. //
  69. //  Parameters:
  70. //     As documented for all WinMain() functions.
  71. //
  72. //  History:   Date       Author      Comment
  73. //              5/ 8/91   BryanW      Wrote it.
  74. //
  75. //---------------------------------------------------------------------------
  76.  
  77. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  78.                     LPSTR lpszCmdLine, int nCmdShow )
  79. {
  80.    HWND  hTTYWnd ;
  81.    MSG   msg ;
  82.  
  83.    if (!hPrevInstance)
  84.       if (!InitApplication( hInstance ))
  85.          return ( FALSE ) ;
  86.  
  87.    if (NULL == (hTTYWnd = InitInstance( hInstance, nCmdShow )))
  88.       return ( FALSE ) ;
  89.  
  90.    while (GetMessage( &msg, NULL, 0, 0 ))
  91.    {
  92.       if (!TranslateAccelerator( hTTYWnd, ghAccel, &msg ))
  93.       {
  94.          TranslateMessage( &msg ) ;
  95.          DispatchMessage( &msg ) ;
  96.       }
  97.    }
  98.    return ( (int) msg.wParam ) ;
  99.  
  100. } // end of WinMain()
  101.  
  102. //---------------------------------------------------------------------------
  103. //  BOOL NEAR InitApplication( HANDLE hInstance )
  104. //
  105. //  Description:
  106. //     First time initialization stuff.  This registers information
  107. //     such as window classes.
  108. //
  109. //  Parameters:
  110. //     HANDLE hInstance
  111. //        Handle to this instance of the application.
  112. //
  113. //  History:   Date       Author      Comment
  114. //              5/ 8/91   BryanW      Wrote it.
  115. //             10/22/91   BryanW      Fixed background color problem.
  116. //
  117. //---------------------------------------------------------------------------
  118.  
  119. BOOL NEAR InitApplication( HANDLE hInstance )
  120. {
  121.    WNDCLASS  wndclass ;
  122.  
  123.    // register tty window class
  124.  
  125.    wndclass.style =         NULL ;
  126.    wndclass.lpfnWndProc =   TTYWndProc ;
  127.    wndclass.cbClsExtra =    0 ;
  128.    wndclass.cbWndExtra =    TTYEXTRABYTES ;
  129.    wndclass.hInstance =     hInstance ;
  130.    wndclass.hIcon =         LoadIcon( hInstance, MAKEINTRESOURCE( TTYICON ) );
  131.    wndclass.hCursor =       LoadCursor( NULL, IDC_ARROW ) ;
  132.    wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  133.    wndclass.lpszMenuName =  MAKEINTRESOURCE( TTYMENU ) ;
  134.    wndclass.lpszClassName = gszTTYClass ;
  135.  
  136.    return( RegisterClass( &wndclass ) ) ;
  137.  
  138. } // end of InitApplication()
  139.  
  140. //---------------------------------------------------------------------------
  141. //  HWND NEAR InitInstance( HANDLE hInstance, int nCmdShow )
  142. //
  143. //  Description:
  144. //     Initializes instance specific information.
  145. //
  146. //  Parameters:
  147. //     HANDLE hInstance
  148. //        Handle to instance
  149. //
  150. //     int nCmdShow
  151. //        How do we show the window?
  152. //
  153. //  History:   Date       Author      Comment
  154. //              5/ 8/91   BryanW      Wrote it.
  155. //
  156. //---------------------------------------------------------------------------
  157.  
  158. HWND NEAR InitInstance( HANDLE hInstance, int nCmdShow )
  159. {
  160.    HWND  hTTYWnd ;
  161.  
  162.    // load accelerators
  163.    ghAccel = LoadAccelerators( hInstance, MAKEINTRESOURCE( TTYACCEL ) ) ;
  164.  
  165.    // create the TTY window
  166.    hTTYWnd = CreateWindow( gszTTYClass, gszAppName,
  167.                            WS_OVERLAPPEDWINDOW,
  168.                            CW_USEDEFAULT, CW_USEDEFAULT,
  169.                            CW_USEDEFAULT, CW_USEDEFAULT,
  170.                            NULL, NULL, hInstance, NULL ) ;
  171.  
  172.    if (NULL == hTTYWnd)
  173.       return ( NULL ) ;
  174.  
  175.    ShowWindow( hTTYWnd, nCmdShow ) ;
  176.    UpdateWindow( hTTYWnd ) ;
  177.  
  178.    return ( hTTYWnd ) ;
  179.  
  180. } // end of InitInstance()
  181.  
  182. //---------------------------------------------------------------------------
  183. //  LRESULT FAR PASCAL TTYWndProc( HWND hWnd, UINT uMsg,
  184. //                                 WPARAM wParam, LPARAM lParam )
  185. //
  186. //  Description:
  187. //     This is the TTY Window Proc.  This handles ALL messages
  188. //     to the tty window.
  189. //
  190. //  Parameters:
  191. //     As documented for Window procedures.
  192. //
  193. //  Win-32 Porting Issues:
  194. //     - WM_HSCROLL and WM_VSCROLL packing is different under Win-32.
  195. //     - Needed LOWORD() of wParam for WM_CHAR messages.
  196. //
  197. //  History:   Date       Author      Comment
  198. //              5/ 9/91   BryanW      Wrote it.
  199. //              6/15/92   BryanW      Kill focus before disconnecting.
  200. //              6/15/92   BryanW      Ported to Win-32.
  201. //
  202. //---------------------------------------------------------------------------
  203.  
  204. LRESULT FAR PASCAL TTYWndProc( HWND hWnd, UINT uMsg,
  205.                                WPARAM wParam, LPARAM lParam )
  206. {
  207.    switch (uMsg)
  208.    {
  209.       case WM_CREATE:
  210.          return ( CreateTTYInfo( hWnd ) ) ;
  211.  
  212.       case WM_COMMAND:
  213.       {
  214.          switch ( LOWORD( wParam ) )
  215.          {
  216.             case IDM_CONNECT:
  217.                if (!OpenConnection( hWnd ))
  218.                   MessageBox( hWnd, "Connection failed.", gszAppName,
  219.                               MB_ICONEXCLAMATION ) ;
  220.                break ;
  221.  
  222.             case IDM_DISCONNECT:
  223.                KillTTYFocus( hWnd ) ;
  224.                CloseConnection( hWnd ) ;
  225.                break ;
  226.  
  227.             case IDM_SETTINGS:
  228.             {
  229.                NPTTYINFO  npTTYInfo ;
  230.  
  231.                if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  232.                   return ( FALSE ) ;
  233.                GoModalDialogBoxParam( GETHINST( hWnd ),
  234.                                       MAKEINTRESOURCE( SETTINGSDLGBOX ), hWnd,
  235.                                       SettingsDlgProc,
  236.                                       (LPARAM) (LPSTR) npTTYInfo ) ;
  237.  
  238.                // if fConnected, set new COM parameters
  239.  
  240.                if (CONNECTED( npTTYInfo ))
  241.                {
  242.                   if (!SetupConnection( hWnd ))
  243.                      MessageBox( hWnd, "Settings failed!", gszAppName,
  244.                                  MB_ICONEXCLAMATION ) ;
  245.                }
  246.             }
  247.             break ;
  248.  
  249.             case IDM_ABOUT:
  250.                GoModalDialogBoxParam ( GETHINST( hWnd ),
  251.                                        MAKEINTRESOURCE( ABOUTDLGBOX ),
  252.                                        hWnd,
  253.                                        AboutDlgProc, NULL ) ;
  254.                break;
  255.  
  256.             case IDM_EXIT:
  257.                PostMessage( hWnd, WM_CLOSE, NULL, 0L ) ;
  258.                break ;
  259.          }
  260.       }
  261.       break ;
  262.  
  263.       case WM_COMMNOTIFY:
  264.          ProcessCOMMNotification( hWnd, wParam, lParam ) ;
  265.          break ;
  266.  
  267.       case WM_PAINT:
  268.          PaintTTY( hWnd ) ;
  269.          break ;
  270.  
  271.       case WM_SIZE:
  272.          SizeTTY( hWnd, HIWORD( lParam ), LOWORD( lParam ) ) ;
  273.          break ;
  274.  
  275.       case WM_HSCROLL:
  276. #ifdef WIN32
  277.          ScrollTTYHorz( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
  278. #else
  279.          ScrollTTYHorz( hWnd, (WORD) wParam, LOWORD( lParam ) ) ;
  280. #endif
  281.          break ;
  282.  
  283.       case WM_VSCROLL:
  284. #ifdef WIN32
  285.          ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
  286. #else
  287.          ScrollTTYVert( hWnd, (WORD) wParam, LOWORD( lParam ) ) ;
  288. #endif
  289.          break ;
  290.  
  291.       case WM_CHAR:
  292. #ifdef WIN32
  293.          ProcessTTYCharacter( hWnd, LOBYTE( LOWORD( wParam ) ) ) ;
  294. #else
  295.          ProcessTTYCharacter( hWnd, LOBYTE( wParam ) ) ;
  296. #endif
  297.          break ;
  298.  
  299.       case WM_SETFOCUS:
  300.          SetTTYFocus( hWnd ) ;
  301.          break ;
  302.  
  303.       case WM_KILLFOCUS:
  304.          KillTTYFocus( hWnd ) ;
  305.          break ;
  306.  
  307.       case WM_DESTROY:
  308.          DestroyTTYInfo( hWnd ) ;
  309.          PostQuitMessage( 0 ) ;
  310.          break ;
  311.  
  312.       case WM_CLOSE:
  313.          if (IDOK != MessageBox( hWnd, "OK to close window?", "TTY Sample",
  314.                                  MB_ICONQUESTION | MB_OKCANCEL ))
  315.             break ;
  316.  
  317.          // fall through
  318.  
  319.       default:
  320.          return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
  321.    }
  322.    return 0L ;
  323.  
  324. } // end of TTYWndProc()
  325.  
  326. //---------------------------------------------------------------------------
  327. //  LRESULT NEAR CreateTTYInfo( HWND hWnd )
  328. //
  329. //  Description:
  330. //     Creates the tty information structure and sets
  331. //     menu option availability.  Returns -1 if unsuccessful.
  332. //
  333. //  Parameters:
  334. //     HWND  hWnd
  335. //        Handle to main window.
  336. //
  337. //  Win-32 Porting Issues:
  338. //     - Needed to initialize TERMWND( npTTYInfo ) for secondary thread.
  339. //     - Needed to create/initialize overlapped structures used in reads &
  340. //       writes to COMM device.
  341. //
  342. //  History:   Date       Author      Comment
  343. //             10/18/91   BryanW      Pulled from tty window proc.
  344. //              1/13/92   BryanW      Fixed bug with invalid handle
  345. //                                    caused by WM_SIZE sent by
  346. //                                    ResetTTYScreen().
  347. //
  348. //---------------------------------------------------------------------------
  349.  
  350. LRESULT NEAR CreateTTYInfo( HWND hWnd )
  351. {
  352.    HMENU       hMenu ;
  353.    NPTTYINFO   npTTYInfo ;
  354.  
  355.    if (NULL == (npTTYInfo =
  356.                    (NPTTYINFO) LocalAlloc( LPTR, sizeof( TTYINFO ) )))
  357.       return ( (LRESULT) -1 ) ;
  358.  
  359.    // initialize TTY info structure
  360.  
  361.    COMDEV( npTTYInfo )        = 0 ;
  362.    CONNECTED( npTTYInfo )     = FALSE ;
  363.    CURSORSTATE( npTTYInfo )   = CS_HIDE ;
  364.    LOCALECHO( npTTYInfo )     = FALSE ;
  365.    AUTOWRAP( npTTYInfo )      = TRUE ;
  366.    PORT( npTTYInfo )          = 1 ;
  367.    BAUDRATE( npTTYInfo )      = CBR_9600 ;
  368.    BYTESIZE( npTTYInfo )      = 8 ;
  369.    FLOWCTRL( npTTYInfo )      = FC_RTSCTS ;
  370.    PARITY( npTTYInfo )        = NOPARITY ;
  371.    STOPBITS( npTTYInfo )      = ONESTOPBIT ;
  372.    XONXOFF( npTTYInfo )       = FALSE ;
  373.    XSIZE( npTTYInfo )         = 0 ;
  374.    YSIZE( npTTYInfo )         = 0 ;
  375.    XSCROLL( npTTYInfo )       = 0 ;
  376.    YSCROLL( npTTYInfo )       = 0 ;
  377.    XOFFSET( npTTYInfo )       = 0 ;
  378.    YOFFSET( npTTYInfo )       = 0 ;
  379.    COLUMN( npTTYInfo )        = 0 ;
  380.    ROW( npTTYInfo )           = 0 ;
  381.    HTTYFONT( npTTYInfo )      = NULL ;
  382.    FGCOLOR( npTTYInfo )       = RGB( 0, 0, 0 ) ;
  383.    USECNRECEIVE( npTTYInfo )  = TRUE ;
  384.    DISPLAYERRORS( npTTYInfo ) = TRUE ;
  385. #ifdef WIN32
  386.    TERMWND( npTTYInfo ) =       hWnd ;
  387.  
  388.    // create I/O event used for overlapped reads / writes
  389.  
  390.    READ_OS( npTTYInfo ).hEvent = CreateEvent( NULL,    // no security
  391.                                               TRUE,    // explicit reset req
  392.                                               FALSE,   // initial event reset
  393.                                               NULL ) ; // no name
  394.    if (READ_OS( npTTYInfo ).hEvent == NULL)
  395.    {
  396.       LocalFree( npTTYInfo ) ;
  397.       return ( -1 ) ;
  398.    }
  399.    WRITE_OS( npTTYInfo ).hEvent = CreateEvent( NULL,    // no security
  400.                                                TRUE,    // explicit reset req
  401.                                                FALSE,   // initial event reset
  402.                                                NULL ) ; // no name
  403.    if (NULL == WRITE_OS( npTTYInfo ).hEvent)
  404.    {
  405.       CloseHandle( READ_OS( npTTYInfo ).hEvent ) ;
  406.       LocalFree( npTTYInfo ) ;
  407.       return ( -1 ) ;
  408.    }
  409.  
  410.    // create "posted notification" event
  411.  
  412.    POSTEVENT( npTTYInfo ) = CreateEvent( NULL,     // no security
  413.                                          TRUE,     // manual reset
  414.                                          TRUE,     // initial event is set
  415.                                          NULL ) ;  // no name
  416.  
  417.    if (POSTEVENT( npTTYInfo ) == NULL)
  418.    {
  419.       CloseHandle( READ_OS( npTTYInfo ).hEvent ) ;
  420.       CloseHandle( WRITE_OS( npTTYInfo ).hEvent ) ;
  421.       LocalFree( npTTYInfo ) ;
  422.       return ( -1 ) ;
  423.    }
  424. #endif
  425.  
  426.    // clear screen space
  427.  
  428.    _fmemset( SCREEN( npTTYInfo ), ' ', MAXROWS * MAXCOLS ) ;
  429.  
  430.    // setup default font information
  431.  
  432.    LFTTYFONT( npTTYInfo ).lfHeight =         9 ;
  433.    LFTTYFONT( npTTYInfo ).lfWidth =          0 ;
  434.    LFTTYFONT( npTTYInfo ).lfEscapement =     0 ;
  435.    LFTTYFONT( npTTYInfo ).lfOrientation =    0 ;
  436.    LFTTYFONT( npTTYInfo ).lfWeight =         0 ;
  437.    LFTTYFONT( npTTYInfo ).lfItalic =         0 ;
  438.    LFTTYFONT( npTTYInfo ).lfUnderline =      0 ;
  439.    LFTTYFONT( npTTYInfo ).lfStrikeOut =      0 ;
  440.    LFTTYFONT( npTTYInfo ).lfCharSet =        OEM_CHARSET ;
  441.    LFTTYFONT( npTTYInfo ).lfOutPrecision =   OUT_DEFAULT_PRECIS ;
  442.    LFTTYFONT( npTTYInfo ).lfClipPrecision =  CLIP_DEFAULT_PRECIS ;
  443.    LFTTYFONT( npTTYInfo ).lfQuality =        DEFAULT_QUALITY ;
  444.    LFTTYFONT( npTTYInfo ).lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
  445.    lstrcpy( LFTTYFONT( npTTYInfo ).lfFaceName, "FixedSys" ) ;
  446.  
  447.    // set TTYInfo handle before any further message processing.
  448.  
  449.    SETNPTTYINFO( hWnd, npTTYInfo ) ;
  450.  
  451.    // reset the character information, etc.
  452.  
  453.    ResetTTYScreen( hWnd, npTTYInfo ) ;
  454.  
  455.    hMenu = GetMenu( hWnd ) ;
  456.    EnableMenuItem( hMenu, IDM_DISCONNECT,
  457.                    MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  458.    EnableMenuItem( hMenu, IDM_CONNECT, MF_ENABLED | MF_BYCOMMAND ) ;
  459.  
  460.    return ( (LRESULT) TRUE ) ;
  461.  
  462. } // end of CreateTTYInfo()
  463.  
  464. //---------------------------------------------------------------------------
  465. //  BOOL NEAR DestroyTTYInfo( HWND hWnd )
  466. //
  467. //  Description:
  468. //     Destroys block associated with TTY window handle.
  469. //
  470. //  Parameters:
  471. //     HWND hWnd
  472. //        handle to TTY window
  473. //
  474. //  Win-32 Porting Issues:
  475. //     - Needed to clean up event objects created during initialization.
  476. //
  477. //  History:   Date       Author      Comment
  478. //              5/ 8/91   BryanW      Wrote it.
  479. //              6/15/92   BryanW      Ported to Win-32.
  480. //
  481. //---------------------------------------------------------------------------
  482.  
  483. BOOL NEAR DestroyTTYInfo( HWND hWnd )
  484. {
  485.    NPTTYINFO npTTYInfo ;
  486.  
  487.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  488.       return ( FALSE ) ;
  489.  
  490.    // force connection closed (if not already closed)
  491.  
  492.    if (CONNECTED( npTTYInfo ))
  493.       CloseConnection( hWnd ) ;
  494.  
  495. #ifdef WIN32
  496.    // clean up event objects
  497.  
  498.    CloseHandle( READ_OS( npTTYInfo ).hEvent ) ;
  499.    CloseHandle( WRITE_OS( npTTYInfo ).hEvent ) ;
  500.    CloseHandle( POSTEVENT( npTTYInfo ) ) ;
  501. #endif
  502.  
  503.    DeleteObject( HTTYFONT( npTTYInfo ) ) ;
  504.  
  505.    LocalFree( npTTYInfo ) ;
  506.    return ( TRUE ) ;
  507.  
  508. } // end of DestroyTTYInfo()
  509.  
  510. //---------------------------------------------------------------------------
  511. //  BOOL NEAR ResetTTYScreen( HWND hWnd, NPTTYINFO npTTYInfo )
  512. //
  513. //  Description:
  514. //     Resets the TTY character information and causes the
  515. //     screen to resize to update the scroll information.
  516. //
  517. //  Parameters:
  518. //     NPTTYINFO  npTTYInfo
  519. //        pointer to TTY info structure
  520. //
  521. //  History:   Date       Author      Comment
  522. //             10/20/91   BryanW      Wrote it.
  523. //
  524. //---------------------------------------------------------------------------
  525.  
  526. BOOL NEAR ResetTTYScreen( HWND hWnd, NPTTYINFO npTTYInfo )
  527. {
  528.    HDC         hDC ;
  529.    TEXTMETRIC  tm ;
  530.    RECT        rcWindow ;
  531.  
  532.    if (NULL == npTTYInfo)
  533.       return ( FALSE ) ;
  534.  
  535.    if (NULL != HTTYFONT( npTTYInfo ))
  536.       DeleteObject( HTTYFONT( npTTYInfo ) ) ;
  537.  
  538.    HTTYFONT( npTTYInfo ) = CreateFontIndirect( &LFTTYFONT( npTTYInfo ) ) ;
  539.  
  540.    hDC = GetDC( hWnd ) ;
  541.    SelectObject( hDC, HTTYFONT( npTTYInfo ) ) ;
  542.    GetTextMetrics( hDC, &tm ) ;
  543.    ReleaseDC( hWnd, hDC ) ;
  544.  
  545.    XCHAR( npTTYInfo ) = tm.tmAveCharWidth  ;
  546.    YCHAR( npTTYInfo ) = tm.tmHeight + tm.tmExternalLeading ;
  547.  
  548.    // a slimy hack to force the scroll position, region to
  549.    // be recalculated based on the new character sizes
  550.  
  551.    GetWindowRect( hWnd, &rcWindow ) ;
  552.    SendMessage( hWnd, WM_SIZE, SIZENORMAL,
  553.                 (LPARAM) MAKELONG( rcWindow.right - rcWindow.left,
  554.                                    rcWindow.bottom - rcWindow.top ) ) ;
  555.  
  556.    return ( TRUE ) ;
  557.  
  558. } // end of ResetTTYScreen()
  559.  
  560. //---------------------------------------------------------------------------
  561. //  BOOL NEAR PaintTTY( HWND hWnd )
  562. //
  563. //  Description:
  564. //     Paints the rectangle determined by the paint struct of
  565. //     the DC.
  566. //
  567. //  Parameters:
  568. //     HWND hWnd
  569. //        handle to TTY window (as always)
  570. //
  571. //  History:   Date       Author      Comment
  572. //              5/ 9/91   BryanW      Wrote it.
  573. //             10/22/91   BryanW      Problem with background color
  574. //                                    and "off by one" fixed.
  575. //
  576. //              2/25/92   BryanW      Off-by-one not quite fixed...
  577. //                                    also resolved min/max problem
  578. //                                    for windows extended beyond
  579. //                                    the "TTY display".
  580. //
  581. //---------------------------------------------------------------------------
  582.  
  583. BOOL NEAR PaintTTY( HWND hWnd )
  584. {
  585.    int          nRow, nCol, nEndRow, nEndCol, nCount, nHorzPos, nVertPos ;
  586.    HDC          hDC ;
  587.    HFONT        hOldFont ;
  588.    NPTTYINFO    npTTYInfo ;
  589.    PAINTSTRUCT  ps ;
  590.    RECT         rect ;
  591.  
  592.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  593.       return ( FALSE ) ;
  594.  
  595.    hDC = BeginPaint( hWnd, &ps ) ;
  596.    hOldFont = SelectObject( hDC, HTTYFONT( npTTYInfo ) ) ;
  597.    SetTextColor( hDC, FGCOLOR( npTTYInfo ) ) ;
  598.    SetBkColor( hDC, GetSysColor( COLOR_WINDOW ) ) ;
  599.    rect = ps.rcPaint ;
  600.    nRow =
  601.       min( MAXROWS - 1,
  602.            max( 0, (rect.top + YOFFSET( npTTYInfo )) / YCHAR( npTTYInfo ) ) ) ;
  603.    nEndRow =
  604.       min( MAXROWS - 1,
  605.            ((rect.bottom + YOFFSET( npTTYInfo ) - 1) / YCHAR( npTTYInfo ) ) ) ;
  606.    nCol =
  607.       min( MAXCOLS - 1,
  608.            max( 0, (rect.left + XOFFSET( npTTYInfo )) / XCHAR( npTTYInfo ) ) ) ;
  609.    nEndCol =
  610.       min( MAXCOLS - 1,
  611.            ((rect.right + XOFFSET( npTTYInfo ) - 1) / XCHAR( npTTYInfo ) ) ) ;
  612.    nCount = nEndCol - nCol + 1 ;
  613.    for (; nRow <= nEndRow; nRow++)
  614.    {
  615.       nVertPos = (nRow * YCHAR( npTTYInfo )) - YOFFSET( npTTYInfo ) ;
  616.       nHorzPos = (nCol * XCHAR( npTTYInfo )) - XOFFSET( npTTYInfo ) ;
  617.       rect.top = nVertPos ;
  618.       rect.bottom = nVertPos + YCHAR( npTTYInfo ) ;
  619.       rect.left = nHorzPos ;
  620.       rect.right = nHorzPos + XCHAR( npTTYInfo ) * nCount ;
  621.       SetBkMode( hDC, OPAQUE ) ;
  622.       ExtTextOut( hDC, nHorzPos, nVertPos, ETO_OPAQUE | ETO_CLIPPED, &rect,
  623.                   (LPSTR)( SCREEN( npTTYInfo ) + nRow * MAXCOLS + nCol ),
  624.                   nCount, NULL ) ;
  625.    }
  626.    SelectObject( hDC, hOldFont ) ;
  627.    EndPaint( hWnd, &ps ) ;
  628.    MoveTTYCursor( hWnd ) ;
  629.    return ( TRUE ) ;
  630.  
  631. } // end of PaintTTY()
  632.  
  633. //---------------------------------------------------------------------------
  634. //  BOOL NEAR SizeTTY( HWND hWnd, WORD wVertSize, WORD wHorzSize )
  635. //
  636. //  Description:
  637. //     Sizes TTY and sets up scrolling regions.
  638. //
  639. //  Parameters:
  640. //     HWND hWnd
  641. //        handle to TTY window
  642. //
  643. //     WORD wVertSize
  644. //        new vertical size
  645. //
  646. //     WORD wHorzSize
  647. //        new horizontal size
  648. //
  649. //  History:   Date       Author      Comment
  650. //              5/ 8/ 91  BryanW      Wrote it
  651. //
  652. //---------------------------------------------------------------------------
  653.  
  654. BOOL NEAR SizeTTY( HWND hWnd, WORD wVertSize, WORD wHorzSize )
  655. {
  656.    int        nScrollAmt ;
  657.    NPTTYINFO  npTTYInfo ;
  658.  
  659.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  660.       return ( FALSE ) ;
  661.  
  662.    YSIZE( npTTYInfo ) = (int) wVertSize ;
  663.    YSCROLL( npTTYInfo ) = max( 0, (MAXROWS * YCHAR( npTTYInfo )) -
  664.                                YSIZE( npTTYInfo ) ) ;
  665.    nScrollAmt = min( YSCROLL( npTTYInfo ), YOFFSET( npTTYInfo ) ) -
  666.                      YOFFSET( npTTYInfo ) ;
  667.    ScrollWindow( hWnd, 0, -nScrollAmt, NULL, NULL ) ;
  668.  
  669.    YOFFSET( npTTYInfo ) = YOFFSET( npTTYInfo ) + nScrollAmt ;
  670.    SetScrollPos( hWnd, SB_VERT, YOFFSET( npTTYInfo ), FALSE ) ;
  671.    SetScrollRange( hWnd, SB_VERT, 0, YSCROLL( npTTYInfo ), TRUE ) ;
  672.  
  673.    XSIZE( npTTYInfo ) = (int) wHorzSize ;
  674.    XSCROLL( npTTYInfo ) = max( 0, (MAXCOLS * XCHAR( npTTYInfo )) -
  675.                                 XSIZE( npTTYInfo ) ) ;
  676.    nScrollAmt = min( XSCROLL( npTTYInfo ), XOFFSET( npTTYInfo )) -
  677.                      XOFFSET( npTTYInfo ) ;
  678.    ScrollWindow( hWnd, 0, -nScrollAmt, NULL, NULL ) ;
  679.    XOFFSET( npTTYInfo ) = XOFFSET( npTTYInfo ) + nScrollAmt ;
  680.    SetScrollPos( hWnd, SB_HORZ, XOFFSET( npTTYInfo ), FALSE ) ;
  681.    SetScrollRange( hWnd, SB_HORZ, 0, XSCROLL( npTTYInfo ), TRUE ) ;
  682.  
  683.    InvalidateRect( hWnd, NULL, TRUE ) ;
  684.  
  685.    return ( TRUE ) ;
  686.  
  687. } // end of SizeTTY()
  688.  
  689. //---------------------------------------------------------------------------
  690. //  BOOL NEAR ScrollTTYVert( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  691. //
  692. //  Description:
  693. //     Scrolls TTY window vertically.
  694. //
  695. //  Parameters:
  696. //     HWND hWnd
  697. //        handle to TTY window
  698. //
  699. //     WORD wScrollCmd
  700. //        type of scrolling we're doing
  701. //
  702. //     WORD wScrollPos
  703. //        scroll position
  704. //
  705. //  History:   Date       Author      Comment
  706. //              5/ 8/91   BryanW      Wrote it.
  707. //
  708. //---------------------------------------------------------------------------
  709.  
  710. BOOL NEAR ScrollTTYVert( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  711. {
  712.    int        nScrollAmt ;
  713.    NPTTYINFO  npTTYInfo ;
  714.  
  715.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  716.       return ( FALSE ) ;
  717.  
  718.    switch (wScrollCmd)
  719.    {
  720.       case SB_TOP:
  721.          nScrollAmt = -YOFFSET( npTTYInfo ) ;
  722.          break ;
  723.  
  724.       case SB_BOTTOM:
  725.          nScrollAmt = YSCROLL( npTTYInfo ) - YOFFSET( npTTYInfo ) ;
  726.          break ;
  727.  
  728.       case SB_PAGEUP:
  729.          nScrollAmt = -YSIZE( npTTYInfo ) ;
  730.          break ;
  731.  
  732.       case SB_PAGEDOWN:
  733.          nScrollAmt = YSIZE( npTTYInfo ) ;
  734.          break ;
  735.  
  736.       case SB_LINEUP:
  737.          nScrollAmt = -YCHAR( npTTYInfo ) ;
  738.          break ;
  739.  
  740.       case SB_LINEDOWN:
  741.          nScrollAmt = YCHAR( npTTYInfo ) ;
  742.          break ;
  743.  
  744.       case SB_THUMBPOSITION:
  745.          nScrollAmt = wScrollPos - YOFFSET( npTTYInfo ) ;
  746.          break ;
  747.  
  748.       default:
  749.          return ( FALSE ) ;
  750.    }
  751.    if ((YOFFSET( npTTYInfo ) + nScrollAmt) > YSCROLL( npTTYInfo ))
  752.       nScrollAmt = YSCROLL( npTTYInfo ) - YOFFSET( npTTYInfo ) ;
  753.    if ((YOFFSET( npTTYInfo ) + nScrollAmt) < 0)
  754.       nScrollAmt = -YOFFSET( npTTYInfo ) ;
  755.    ScrollWindow( hWnd, 0, -nScrollAmt, NULL, NULL ) ;
  756.    YOFFSET( npTTYInfo ) = YOFFSET( npTTYInfo ) + nScrollAmt ;
  757.    SetScrollPos( hWnd, SB_VERT, YOFFSET( npTTYInfo ), TRUE ) ;
  758.  
  759.    return ( TRUE ) ;
  760.  
  761. } // end of ScrollTTYVert()
  762.  
  763. //---------------------------------------------------------------------------
  764. //  BOOL NEAR ScrollTTYHorz( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  765. //
  766. //  Description:
  767. //     Scrolls TTY window horizontally.
  768. //
  769. //  Parameters:
  770. //     HWND hWnd
  771. //        handle to TTY window
  772. //
  773. //     WORD wScrollCmd
  774. //        type of scrolling we're doing
  775. //
  776. //     WORD wScrollPos
  777. //        scroll position
  778. //
  779. //  History:   Date       Author      Comment
  780. //              5/ 8/91   BryanW      Wrote it.
  781. //
  782. //---------------------------------------------------------------------------
  783.  
  784. BOOL NEAR ScrollTTYHorz( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  785. {
  786.    int        nScrollAmt ;
  787.    NPTTYINFO  npTTYInfo ;
  788.  
  789.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  790.       return ( FALSE ) ;
  791.  
  792.    switch (wScrollCmd)
  793.    {
  794.       case SB_TOP:
  795.          nScrollAmt = -XOFFSET( npTTYInfo ) ;
  796.          break ;
  797.  
  798.       case SB_BOTTOM:
  799.          nScrollAmt = XSCROLL( npTTYInfo ) - XOFFSET( npTTYInfo ) ;
  800.          break ;
  801.  
  802.       case SB_PAGEUP:
  803.          nScrollAmt = -XSIZE( npTTYInfo ) ;
  804.          break ;
  805.  
  806.       case SB_PAGEDOWN:
  807.          nScrollAmt = XSIZE( npTTYInfo ) ;
  808.          break ;
  809.  
  810.       case SB_LINEUP:
  811.          nScrollAmt = -XCHAR( npTTYInfo ) ;
  812.          break ;
  813.  
  814.       case SB_LINEDOWN:
  815.          nScrollAmt = XCHAR( npTTYInfo ) ;
  816.          break ;
  817.  
  818.       case SB_THUMBPOSITION:
  819.          nScrollAmt = wScrollPos - XOFFSET( npTTYInfo ) ;
  820.          break ;
  821.  
  822.       default:
  823.          return ( FALSE ) ;
  824.    }
  825.    if ((XOFFSET( npTTYInfo ) + nScrollAmt) > XSCROLL( npTTYInfo ))
  826.       nScrollAmt = XSCROLL( npTTYInfo ) - XOFFSET( npTTYInfo ) ;
  827.    if ((XOFFSET( npTTYInfo ) + nScrollAmt) < 0)
  828.       nScrollAmt = -XOFFSET( npTTYInfo ) ;
  829.    ScrollWindow( hWnd, -nScrollAmt, 0, NULL, NULL ) ;
  830.    XOFFSET( npTTYInfo ) = XOFFSET( npTTYInfo ) + nScrollAmt ;
  831.    SetScrollPos( hWnd, SB_HORZ, XOFFSET( npTTYInfo ), TRUE ) ;
  832.  
  833.    return ( TRUE ) ;
  834.  
  835. } // end of ScrollTTYHorz()
  836.  
  837. //---------------------------------------------------------------------------
  838. //  BOOL NEAR SetTTYFocus( HWND hWnd )
  839. //
  840. //  Description:
  841. //     Sets the focus to the TTY window also creates caret.
  842. //
  843. //  Parameters:
  844. //     HWND hWnd
  845. //        handle to TTY window
  846. //
  847. //  History:   Date       Author      Comment
  848. //              5/ 9/91   BryanW      Wrote it.
  849. //
  850. //---------------------------------------------------------------------------
  851.  
  852. BOOL NEAR SetTTYFocus( HWND hWnd )
  853. {
  854.    NPTTYINFO  npTTYInfo ;
  855.  
  856.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  857.       return ( FALSE ) ;
  858.  
  859.    if (CONNECTED( npTTYInfo ) && (CURSORSTATE( npTTYInfo ) != CS_SHOW))
  860.    {
  861.       CreateCaret( hWnd, NULL, XCHAR( npTTYInfo ), YCHAR( npTTYInfo ) ) ;
  862.       ShowCaret( hWnd ) ;
  863.       CURSORSTATE( npTTYInfo ) = CS_SHOW ;
  864.    }
  865.    MoveTTYCursor( hWnd ) ;
  866.    return ( TRUE ) ;
  867.  
  868. } // end of SetTTYFocus()
  869.  
  870. //---------------------------------------------------------------------------
  871. //  BOOL NEAR KillTTYFocus( HWND hWnd )
  872. //
  873. //  Description:
  874. //     Kills TTY focus and destroys the caret.
  875. //
  876. //  Parameters:
  877. //     HWND hWnd
  878. //        handle to TTY window
  879. //
  880. //  History:   Date       Author      Comment
  881. //              5/ 9/91   BryanW      Wrote it.
  882. //
  883. //---------------------------------------------------------------------------
  884.  
  885. BOOL NEAR KillTTYFocus( HWND hWnd )
  886. {
  887.    NPTTYINFO  npTTYInfo ;
  888.  
  889.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  890.       return ( FALSE ) ;
  891.  
  892.    if (CONNECTED( npTTYInfo ) && (CURSORSTATE( npTTYInfo ) != CS_HIDE))
  893.    {
  894.       HideCaret( hWnd ) ;
  895.       DestroyCaret() ;
  896.       CURSORSTATE( npTTYInfo ) = CS_HIDE ;
  897.    }
  898.    return ( TRUE ) ;
  899.  
  900. } // end of KillTTYFocus()
  901.  
  902. //---------------------------------------------------------------------------
  903. //  BOOL NEAR MoveTTYCursor( HWND hWnd )
  904. //
  905. //  Description:
  906. //     Moves caret to current position.
  907. //
  908. //  Parameters:
  909. //     HWND hWnd
  910. //        handle to TTY window
  911. //
  912. //  History:   Date       Author      Comment
  913. //              5/ 9/91   BryanW      Wrote it.
  914. //
  915. //---------------------------------------------------------------------------
  916.  
  917. BOOL NEAR MoveTTYCursor( HWND hWnd )
  918. {
  919.    NPTTYINFO  npTTYInfo ;
  920.  
  921.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  922.       return ( FALSE ) ;
  923.  
  924.    if (CONNECTED( npTTYInfo ) && (CURSORSTATE( npTTYInfo ) & CS_SHOW))
  925.       SetCaretPos( (COLUMN( npTTYInfo ) * XCHAR( npTTYInfo )) -
  926.                    XOFFSET( npTTYInfo ),
  927.                    (ROW( npTTYInfo ) * YCHAR( npTTYInfo )) -
  928.                    YOFFSET( npTTYInfo ) ) ;
  929.    
  930.    return ( TRUE ) ;
  931.  
  932. } // end of MoveTTYCursor()
  933.  
  934. //---------------------------------------------------------------------------
  935. //  BOOL NEAR ProcessCOMMNotification( HWND hWnd,
  936. //                                     WPARAM wParam, LPARAM lParam ) ;
  937. //
  938. //  Description:
  939. //     Processes the WM_COMMNOTIFY message from the COMM.DRV.
  940. //
  941. //  Parameters:
  942. //     HWND hWnd
  943. //        handle to TTY window
  944. //
  945. //     WPARAM wParam
  946. //        specifes the device (nCid)
  947. //
  948. //     LPARAM lParam
  949. //        LOWORD contains event trigger
  950. //        HIWORD is NULL
  951. //
  952. //  Win-32 Porting Issues:
  953. //     - Function was constrained by WORD and LONG declarations.
  954. //     - Processing under Win-32 is much simpler and additionally
  955. //       requires the "posted message" flag to be cleared.
  956. //
  957. //  History:   Date       Author      Comment
  958. //              5/10/91   BryanW      Wrote it.
  959. //             10/18/91   BryanW      Updated to verify the event.
  960. //              6/15/92   BryanW      Removed WORD and LONG constraints.
  961. //              6/15/92   BryanW      Ported to Win-32.
  962. //
  963. //---------------------------------------------------------------------------
  964.  
  965. BOOL NEAR ProcessCOMMNotification( HWND hWnd, WPARAM wParam, LPARAM lParam )
  966. {
  967.    int        nLength ;
  968.    BYTE       abIn[ MAXBLOCK + 1] ;
  969.    NPTTYINFO  npTTYInfo ;
  970.    MSG        msg ;
  971.  
  972.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  973.       return ( FALSE ) ;
  974.  
  975.    if (!CONNECTED( npTTYInfo ))
  976.       return ( FALSE ) ;
  977.  
  978. #ifdef WIN32
  979.    // verify that it is a COMM event sent by our thread
  980.  
  981.    if (CN_EVENT & LOWORD( lParam ) != CN_EVENT)
  982.       return ( FALSE ) ;
  983.  
  984.    // We loop here since it is highly likely that the buffer
  985.    // can been filled while we are reading this block.  This
  986.    // is especially true when operating at high baud rates
  987.    // (e.g. >= 9600 baud).
  988.  
  989.    do
  990.    {
  991.       if (nLength = ReadCommBlock( hWnd, (LPSTR) abIn, MAXBLOCK ))
  992.       {
  993.          WriteTTYBlock( hWnd, (LPSTR) abIn, nLength ) ;
  994.  
  995.          // force a paint
  996.  
  997.          UpdateWindow( hWnd ) ;
  998.       }
  999.    }
  1000.    while (!PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE) || (nLength > 0)) ;
  1001.  
  1002.    // clear our "posted notification" flag
  1003.  
  1004.    SetEvent( POSTEVENT( npTTYInfo ) ) ;
  1005. #else
  1006.    if (!USECNRECEIVE( npTTYInfo ))
  1007.    {
  1008.       // verify that it is a COMM event specified by our mask
  1009.  
  1010.       if (CN_EVENT & LOWORD( lParam ) != CN_EVENT)
  1011.          return ( FALSE ) ;
  1012.  
  1013.       // For Windows 3.1, rested reset the event word so we are notified
  1014.       // when the next event occurs
  1015.  
  1016.       GetCommEventMask( COMDEV( npTTYInfo ), EV_RXCHAR ) ;
  1017.  
  1018.       // We loop here since it is highly likely that the buffer
  1019.       // can been filled while we are reading this block.  This
  1020.       // is especially true when operating at high baud rates
  1021.       // (e.g. >= 9600 baud).
  1022.  
  1023.       do
  1024.       {
  1025.          if (nLength = ReadCommBlock( hWnd, (LPSTR) abIn, MAXBLOCK ))
  1026.          {
  1027.             WriteTTYBlock( hWnd, (LPSTR) abIn, nLength ) ;
  1028.  
  1029.             // force a paint
  1030.  
  1031.             UpdateWindow( hWnd ) ;
  1032.          }
  1033.       }
  1034.       while (!PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE) || (nLength > 0)) ;
  1035.    }
  1036.    else
  1037.    {
  1038.       // verify that it is a receive event
  1039.  
  1040.       if (CN_RECEIVE & LOWORD( lParam ) != CN_RECEIVE)
  1041.          return ( FALSE ) ;
  1042.  
  1043.       do
  1044.       {
  1045.          if (nLength = ReadCommBlock( hWnd, (LPSTR) abIn, MAXBLOCK ))
  1046.          {
  1047.             WriteTTYBlock( hWnd, (LPSTR) abIn, nLength ) ;
  1048.  
  1049.             // force a paint
  1050.  
  1051.             UpdateWindow( hWnd ) ;
  1052.          }
  1053.       }
  1054.       while ((!PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )) ||
  1055.             (ComStat.cbInQue >= MAXBLOCK)) ;
  1056.    }
  1057. #endif
  1058.  
  1059.    return ( TRUE ) ;
  1060.  
  1061. } // end of ProcessCOMMNotification()
  1062.  
  1063. //---------------------------------------------------------------------------
  1064. //  BOOL NEAR ProcessTTYCharacter( HWND hWnd, BYTE bOut )
  1065. //
  1066. //  Description:
  1067. //     This simply writes a character to the port and echos it
  1068. //     to the TTY screen if fLocalEcho is set.  Some minor
  1069. //     keyboard mapping could be performed here.
  1070. //
  1071. //  Parameters:
  1072. //     HWND hWnd
  1073. //        handle to TTY window
  1074. //
  1075. //     BYTE bOut
  1076. //        byte from keyboard
  1077. //
  1078. //  History:   Date       Author      Comment
  1079. //              5/11/91   BryanW      Wrote it.
  1080. //
  1081. //---------------------------------------------------------------------------
  1082.  
  1083. BOOL NEAR ProcessTTYCharacter( HWND hWnd, BYTE bOut )
  1084. {
  1085.    NPTTYINFO  npTTYInfo ;
  1086.  
  1087.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1088.       return ( FALSE ) ;
  1089.  
  1090.    if (!CONNECTED( npTTYInfo ))
  1091.       return ( FALSE ) ;
  1092.  
  1093.    WriteCommByte( hWnd, bOut ) ;
  1094.    if (LOCALECHO( npTTYInfo ))
  1095.       WriteTTYBlock( hWnd, &bOut, 1 ) ;
  1096.  
  1097.    return ( TRUE ) ;
  1098.  
  1099. } // end of ProcessTTYCharacter()
  1100.  
  1101. //---------------------------------------------------------------------------
  1102. //  BOOL NEAR OpenConnection( HWND hWnd )
  1103. //
  1104. //  Description:
  1105. //     Opens communication port specified in the TTYINFO struct.
  1106. //     It also sets the CommState and notifies the window via
  1107. //     the fConnected flag in the TTYINFO struct.
  1108. //
  1109. //  Parameters:
  1110. //     HWND hWnd
  1111. //        handle to TTY window
  1112. //
  1113. //  Win-32 Porting Issues:
  1114. //     - OpenComm() is not supported under Win-32.  Use CreateFile()
  1115. //       and setup for OVERLAPPED_IO.
  1116. //     - Win-32 has specific communication timeout parameters.
  1117. //     - Created the secondary thread for event notification.
  1118. //
  1119. //  History:   Date       Author      Comment
  1120. //              5/ 9/91   BryanW      Wrote it.
  1121. //
  1122. //---------------------------------------------------------------------------
  1123.  
  1124. BOOL NEAR OpenConnection( HWND hWnd )
  1125. {            
  1126.    char       szPort[ 15 ], szTemp[ 10 ] ;
  1127.    BOOL       fRetVal ;
  1128.    HCURSOR    hOldCursor, hWaitCursor ;
  1129.    HMENU      hMenu ;
  1130.    NPTTYINFO  npTTYInfo ;
  1131.  
  1132. #ifdef WIN32
  1133.    HANDLE        hCommWatchThread ;
  1134.    DWORD         dwThreadID ;
  1135.    COMMTIMEOUTS  CommTimeOuts ;
  1136. #endif
  1137.  
  1138.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1139.       return ( FALSE ) ;
  1140.  
  1141.    // show the hourglass cursor
  1142.    hWaitCursor = LoadCursor( NULL, IDC_WAIT ) ;
  1143.    hOldCursor = SetCursor( hWaitCursor ) ;
  1144.  
  1145. #ifdef WIN32
  1146.    // HACK!  This checks for the PORT number defined by
  1147.    // the combo box selection.  If it is greater than the
  1148.    // maximum number of ports, assume TELNET.
  1149.  
  1150.    if (PORT( npTTYInfo ) > MAXPORTS)
  1151.       lstrcpy( szPort, "\\\\.\\TELNET" ) ;
  1152.    else
  1153.    {
  1154.       // load the COM prefix string and append port number
  1155.    
  1156.       LoadString( GETHINST( hWnd ), IDS_COMPREFIX, szTemp, sizeof( szTemp ) ) ;
  1157.       wsprintf( szPort, "%s%d", (LPSTR) szTemp, PORT( npTTYInfo ) ) ;
  1158.    }
  1159. #else
  1160.    // load the COM prefix string and append port number
  1161.  
  1162.    LoadString( GETHINST( hWnd ), IDS_COMPREFIX, szTemp, sizeof( szTemp ) ) ;
  1163.    wsprintf( szPort, "%s%d", (LPSTR) szTemp, PORT( npTTYInfo ) ) ;
  1164. #endif
  1165.  
  1166.    // open COMM device
  1167.  
  1168. #ifdef WIN32
  1169.    if ((COMDEV( npTTYInfo ) =
  1170.       CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
  1171.                   0,                    // exclusive access
  1172.                   NULL,                 // no security attrs
  1173.                   OPEN_EXISTING,
  1174.                   FILE_ATTRIBUTE_NORMAL | 
  1175.                   FILE_FLAG_OVERLAPPED, // overlapped I/O
  1176.                   NULL )) == (HANDLE) -1 )
  1177.       return ( FALSE ) ;
  1178.    else
  1179.    {
  1180.       // get any early notifications
  1181.  
  1182.       SetCommMask( COMDEV( npTTYInfo ), EV_RXCHAR ) ;
  1183.  
  1184.       // setup device buffers
  1185.  
  1186.       SetupComm( COMDEV( npTTYInfo ), 4096, 4096 ) ;
  1187.  
  1188.       // purge any information in the buffer
  1189.  
  1190.       // HACK! HACK! Not really needed... the buffers are allocated
  1191.       // and clear.  If TELNET is active, the buffer will contain
  1192.       // immediate data.
  1193.  
  1194. //      PurgeComm( COMDEV( npTTYInfo ), PURGE_TXABORT | PURGE_RXABORT |
  1195. //                                      PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
  1196.  
  1197.       // set up for overlapped non-blocking I/O
  1198.  
  1199.       CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
  1200.       CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
  1201.       CommTimeOuts.ReadTotalTimeoutConstant = 0 ;
  1202.       CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
  1203.       CommTimeOuts.WriteTotalTimeoutConstant = 5000 ;
  1204.       SetCommTimeouts( COMDEV( npTTYInfo ), &CommTimeOuts ) ;
  1205.    }
  1206. #else
  1207.    if ((COMDEV( npTTYInfo ) = OpenComm( szPort, RXQUEUE, TXQUEUE )) < 0)
  1208.       return ( FALSE ) ;
  1209. #endif
  1210.  
  1211.    fRetVal = SetupConnection( hWnd ) ;
  1212.  
  1213.    if (fRetVal)
  1214.    {
  1215.       CONNECTED( npTTYInfo ) = TRUE ;
  1216.  
  1217. #ifdef WIN32
  1218.       // In the case of Win32, we create a secondary thread
  1219.       // to watch for an event.
  1220.  
  1221.       if (NULL == (hCommWatchThread =
  1222.                       CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
  1223.                                     0, 
  1224.                                     (LPTHREAD_START_ROUTINE) CommWatchProc,
  1225.                                     (LPVOID) npTTYInfo,
  1226.                                     NULL, &dwThreadID )))
  1227.       {
  1228.          CONNECTED( npTTYInfo ) = FALSE ;
  1229.          CloseHandle( COMDEV( npTTYInfo ) ) ;
  1230.          fRetVal = FALSE ;
  1231.       }
  1232.       else
  1233.       {
  1234.          THREADID( npTTYInfo ) = dwThreadID ;
  1235.          HTHREAD( npTTYInfo ) = hCommWatchThread ;
  1236.  
  1237.          // Adjust thread priority
  1238.         
  1239.          SetThreadPriority( hCommWatchThread, THREAD_PRIORITY_BELOW_NORMAL ) ;
  1240.          ResumeThread( hCommWatchThread ) ;
  1241.  
  1242.          // assert DTR
  1243.  
  1244.          EscapeCommFunction( COMDEV( npTTYInfo ), SETDTR ) ;
  1245.  
  1246.          SetTTYFocus( hWnd ) ;
  1247.  
  1248.          hMenu = GetMenu( hWnd ) ;
  1249.          EnableMenuItem( hMenu, IDM_DISCONNECT,
  1250.                         MF_ENABLED | MF_BYCOMMAND ) ;
  1251.          EnableMenuItem( hMenu, IDM_CONNECT,
  1252.                         MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  1253.  
  1254.          // kick TELNET into operation
  1255.  
  1256.          ProcessCOMMNotification( hWnd, (WPARAM) COMDEV( npTTYInfo ), 
  1257.                                   MAKELONG( CN_EVENT, 0 ) ) ;
  1258.  
  1259.       }
  1260. #else
  1261.       // Under Windows 3.1, we set up notifications from COMM.DRV
  1262.  
  1263.       if (!USECNRECEIVE( npTTYInfo ))
  1264.       {
  1265.          // In this case we really are only using the notifications
  1266.          // for the received characters - it could be expanded to
  1267.          // cover the changes in CD or other status lines.
  1268.  
  1269.          SetCommEventMask( COMDEV( npTTYInfo ), EV_RXCHAR ) ;
  1270.  
  1271.          // Enable notifications for events only.
  1272.       
  1273.          // NB:  This method does not use the specific
  1274.          // in/out queue triggers.
  1275.  
  1276.          EnableCommNotification( COMDEV( npTTYInfo ), hWnd, -1, -1 ) ;
  1277.       }
  1278.       else
  1279.       {
  1280.          // Enable notification for CN_RECEIVE events.
  1281.  
  1282.          EnableCommNotification( COMDEV( npTTYInfo ), hWnd, MAXBLOCK, -1 ) ;
  1283.       }
  1284.  
  1285.       // assert DTR
  1286.  
  1287.       EscapeCommFunction( COMDEV( npTTYInfo ), SETDTR ) ;
  1288.  
  1289.       SetTTYFocus( hWnd ) ;
  1290.  
  1291.       hMenu = GetMenu( hWnd ) ;
  1292.       EnableMenuItem( hMenu, IDM_DISCONNECT,
  1293.                       MF_ENABLED | MF_BYCOMMAND ) ;
  1294.       EnableMenuItem( hMenu, IDM_CONNECT,
  1295.                       MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  1296. #endif
  1297.    }
  1298.    else
  1299.    {
  1300.       CONNECTED( npTTYInfo ) = FALSE ;
  1301.  
  1302. #ifdef WIN32
  1303.       CloseHandle( COMDEV( npTTYInfo ) ) ;
  1304. #else
  1305.       CloseComm( COMDEV( npTTYInfo ) ) ;
  1306. #endif
  1307.    }
  1308.  
  1309.    // restore cursor
  1310.  
  1311.    SetCursor( hOldCursor ) ;
  1312.  
  1313.    return ( fRetVal ) ;
  1314.  
  1315. } // end of OpenConnection()
  1316.  
  1317. //---------------------------------------------------------------------------
  1318. //  BOOL NEAR SetupConnection( HWND hWnd )
  1319. //
  1320. //  Description:
  1321. //     This routines sets up the DCB based on settings in the
  1322. //     TTY info structure and performs a SetCommState().
  1323. //
  1324. //  Parameters:
  1325. //     HWND hWnd
  1326. //        handle to TTY window
  1327. //
  1328. //  Win-32 Porting Issues:
  1329. //     - Win-32 requires a slightly different processing of the DCB.
  1330. //       Changes were made for configuration of the hardware handshaking
  1331. //       lines.
  1332. //
  1333. //  History:   Date       Author      Comment
  1334. //              5/ 9/91   BryanW      Wrote it.
  1335. //
  1336. //---------------------------------------------------------------------------
  1337.  
  1338. BOOL NEAR SetupConnection( HWND hWnd )
  1339. {
  1340.    BOOL       fRetVal ;
  1341.    BYTE       bSet ;
  1342.    DCB        dcb ;
  1343.    NPTTYINFO  npTTYInfo ;
  1344.  
  1345.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1346.       return ( FALSE ) ;
  1347.  
  1348. #ifdef WIN32
  1349.    dcb.DCBlength = sizeof( DCB ) ;
  1350. #endif
  1351.  
  1352.    GetCommState( COMDEV( npTTYInfo ), &dcb ) ;
  1353.  
  1354.    dcb.BaudRate = BAUDRATE( npTTYInfo ) ;
  1355.    dcb.ByteSize = BYTESIZE( npTTYInfo ) ;
  1356.    dcb.Parity = PARITY( npTTYInfo ) ;
  1357.    dcb.StopBits = STOPBITS( npTTYInfo ) ;
  1358.  
  1359.    // setup hardware flow control
  1360.  
  1361.    bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_DTRDSR) != 0) ;
  1362. #ifdef WIN32
  1363.    dcb.fOutxDsrFlow = bSet ;
  1364.    if (bSet)
  1365.       dcb.fDtrControl = DTR_CONTROL_HANDSHAKE ;
  1366.    else
  1367.       dcb.fDtrControl = DTR_CONTROL_ENABLE ;
  1368. #else
  1369.    dcb.fOutxDsrFlow = dcb.fDtrflow = bSet ;
  1370.    dcb.DsrTimeout = (bSet) ? 30 : 0 ;
  1371. #endif
  1372.  
  1373.    bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_RTSCTS) != 0) ;
  1374. #ifdef WIN32
  1375.    dcb.fOutxCtsFlow = bSet ;
  1376.    if (bSet)
  1377.       dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ;
  1378.    else
  1379.       dcb.fRtsControl = RTS_CONTROL_ENABLE ;
  1380. #else
  1381.    dcb.fOutxCtsFlow = dcb.fRtsflow = bSet ;
  1382.    dcb.CtsTimeout = (bSet) ? 30 : 0 ;
  1383. #endif
  1384.  
  1385.    // setup software flow control
  1386.  
  1387.    bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_XONXOFF) != 0) ;
  1388.  
  1389.    dcb.fInX = dcb.fOutX = bSet ;
  1390.    dcb.XonChar = ASCII_XON ;
  1391.    dcb.XoffChar = ASCII_XOFF ;
  1392.    dcb.XonLim = 100 ;
  1393.    dcb.XoffLim = 100 ;
  1394.  
  1395.    // other various settings
  1396.  
  1397.    dcb.fBinary = TRUE ;
  1398.    dcb.fParity = TRUE ;
  1399.  
  1400. #ifndef WIN32
  1401.    dcb.fRtsDisable = FALSE ;
  1402.    dcb.fDtrDisable = FALSE ;
  1403.    fRetVal = !(SetCommState( &dcb ) < 0) ;
  1404. #else
  1405.    fRetVal = SetCommState( COMDEV( npTTYInfo ), &dcb ) ;
  1406. #endif
  1407.  
  1408.    return ( fRetVal ) ;
  1409.  
  1410. } // end of SetupConnection()
  1411.  
  1412. //---------------------------------------------------------------------------
  1413. //  BOOL NEAR CloseConnection( HWND hWnd )
  1414. //
  1415. //  Description:
  1416. //     Closes the connection to the port.  Resets the connect flag
  1417. //     in the TTYINFO struct.
  1418. //
  1419. //  Parameters:
  1420. //     HWND hWnd
  1421. //        handle to TTY window
  1422. //
  1423. //  Win-32 Porting Issues:
  1424. //     - Needed to stop secondary thread.  SetCommMask() will signal the
  1425. //       WaitCommEvent() event and the thread will halt when the
  1426. //       CONNECTED() flag is clear.
  1427. //     - Use new PurgeComm() API to clear communications driver before
  1428. //       closing device.
  1429. //
  1430. //  History:   Date       Author      Comment
  1431. //              5/ 9/91   BryanW      Wrote it.
  1432. //              6/15/92   BryanW      Ported to Win-32.
  1433. //
  1434. //---------------------------------------------------------------------------
  1435.  
  1436. BOOL NEAR CloseConnection( HWND hWnd )
  1437. {
  1438.    HMENU      hMenu ;
  1439.    NPTTYINFO  npTTYInfo ;
  1440.  
  1441.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1442.       return ( FALSE ) ;
  1443.  
  1444.    // set connected flag to FALSE
  1445.  
  1446.    CONNECTED( npTTYInfo ) = FALSE ;
  1447.  
  1448. #ifdef WIN32
  1449.    // disable event notification and wait for thread
  1450.    // to halt
  1451.  
  1452.    SetCommMask( COMDEV( npTTYInfo ), NULL ) ;
  1453.  
  1454.    // block until thread has been halted
  1455.  
  1456.    while (THREADID( npTTYInfo ) != NULL) ;
  1457. #else
  1458.    // Disable event notification.  Using a NULL hWnd tells
  1459.    // the COMM.DRV to disable future notifications.
  1460.  
  1461.    EnableCommNotification( COMDEV( npTTYInfo ), NULL, -1, -1 ) ;
  1462. #endif
  1463.  
  1464.    // kill the focus
  1465.  
  1466.    KillTTYFocus( hWnd ) ;
  1467.  
  1468. #ifdef WIN32
  1469.    // drop DTR
  1470.  
  1471.    EscapeCommFunction( COMDEV( npTTYInfo ), CLRDTR ) ;
  1472.  
  1473.    // purge any outstanding reads/writes and close device handle
  1474.  
  1475.    PurgeComm( COMDEV( npTTYInfo ), PURGE_TXABORT | PURGE_RXABORT |
  1476.                                    PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
  1477.    CloseHandle( COMDEV( npTTYInfo ) ) ;
  1478. #else
  1479.    // drop DTR
  1480.  
  1481.    EscapeCommFunction( COMDEV( npTTYInfo ), CLRDTR ) ;
  1482.  
  1483.    // close comm connection
  1484.  
  1485.    CloseComm( COMDEV( npTTYInfo ) ) ;
  1486. #endif
  1487.  
  1488.    // change the selectable items in the menu
  1489.  
  1490.    hMenu = GetMenu( hWnd ) ;
  1491.    EnableMenuItem( hMenu, IDM_DISCONNECT,
  1492.                    MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  1493.    EnableMenuItem( hMenu, IDM_CONNECT,
  1494.                    MF_ENABLED | MF_BYCOMMAND ) ;
  1495.  
  1496.    return ( TRUE ) ;
  1497.  
  1498. } // end of CloseConnection()
  1499.  
  1500. //---------------------------------------------------------------------------
  1501. //  int NEAR ReadCommBlock( HWND hWnd, LPSTR lpszBlock, int nMaxLength )
  1502. //
  1503. //  Description:
  1504. //     Reads a block from the COM port and stuffs it into
  1505. //     the provided block.
  1506. //
  1507. //  Parameters:
  1508. //     HWND hWnd
  1509. //        handle to TTY window
  1510. //
  1511. //     LPSTR lpszBlock
  1512. //        block used for storage
  1513. //
  1514. //     int nMaxLength
  1515. //        max length of block to read
  1516. //
  1517. //  Win-32 Porting Issues:
  1518. //     - ReadComm() has been replaced by ReadFile() in Win-32.
  1519. //     - Overlapped I/O has been implemented.
  1520. //
  1521. //  History:   Date       Author      Comment
  1522. //              5/10/91   BryanW      Wrote it.
  1523. //
  1524. //---------------------------------------------------------------------------
  1525.  
  1526. int NEAR ReadCommBlock( HWND hWnd, LPSTR lpszBlock, int nMaxLength )
  1527. {
  1528. #ifdef WIN32
  1529.    BOOL       fReadStat ;
  1530.    COMSTAT    ComStat ;
  1531.    DWORD      dwErrorFlags, dwLength ;
  1532. #else
  1533.    int        nError, nLength ;
  1534. #endif
  1535.  
  1536.    char       szError[ 10 ] ;
  1537.    NPTTYINFO  npTTYInfo ;
  1538.  
  1539.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1540.       return ( FALSE ) ;
  1541.  
  1542. #ifdef WIN32
  1543.    ClearCommError( COMDEV( npTTYInfo ), &dwErrorFlags, &ComStat ) ;
  1544.    if ((dwErrorFlags > 0) && DISPLAYERRORS( npTTYInfo ))
  1545.    {
  1546.       wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
  1547.       WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  1548.    }
  1549.  
  1550.    // BUG! BUG!  BETA 1 TELNET returns BOGUS data here, so a temporary
  1551.    // hack is used... always attempt to read "maxlength" bytes.
  1552.  
  1553. //   dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
  1554.  
  1555.    dwLength = nMaxLength ;
  1556.  
  1557.    if (dwLength > 0)
  1558.    {
  1559.       fReadStat = ReadFile( COMDEV( npTTYInfo ), lpszBlock,
  1560.                             dwLength, &dwLength, &READ_OS( npTTYInfo ) ) ;
  1561.       if (!fReadStat)
  1562.       {
  1563.          if (GetLastError() == ERROR_IO_PENDING)
  1564.          {
  1565.             // wait for a second for this transmission to complete
  1566.  
  1567.             if (WaitForSingleObject( READ_OS( npTTYInfo ).hEvent, 1000 ))
  1568.                dwLength = 0 ;
  1569.             else
  1570.             {
  1571.                GetOverlappedResult( COMDEV( npTTYInfo ),
  1572.                                     &READ_OS( npTTYInfo ),
  1573.                                     &dwLength, FALSE ) ;
  1574.                READ_OS( npTTYInfo ).Offset += dwLength ;
  1575.             }
  1576.          }
  1577.          else
  1578.             // some other error occurred
  1579.  
  1580.             dwLength = 0 ;
  1581.       }
  1582.    }
  1583.  
  1584.    return ( dwLength ) ;
  1585. #else
  1586.    nLength = ReadComm( COMDEV( npTTYInfo ), lpszBlock, nMaxLength ) ;
  1587.  
  1588.    if (nLength < 0)
  1589.    {
  1590.       nLength *= -1 ;
  1591.       while (nError = GetCommError( COMDEV( npTTYInfo ), NULL ))
  1592.       {
  1593.          if (DISPLAYERRORS( npTTYInfo ))
  1594.          {
  1595.             wsprintf( szError, "<CE-%d>", nError ) ;
  1596.             WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  1597.          }
  1598.       }
  1599.    }
  1600.    return ( nLength ) ;
  1601. #endif
  1602.  
  1603.  
  1604. } // end of ReadCommBlock()
  1605.  
  1606. //---------------------------------------------------------------------------
  1607. //  BOOL NEAR WriteCommByte( HWND hWnd, BYTE bByte )
  1608. //
  1609. //  Description:
  1610. //     Writes a byte to the COM port specified in the associated
  1611. //     TTY info structure.
  1612. //
  1613. //  Parameters:
  1614. //     HWND hWnd
  1615. //        handle to TTY window
  1616. //
  1617. //     BYTE bByte
  1618. //        byte to write to port
  1619. //
  1620. //  Win-32 Porting Issues:
  1621. //     - WriteComm() has been replaced by WriteFile() in Win-32.
  1622. //     - Overlapped I/O has been implemented.
  1623. //
  1624. //  History:   Date       Author      Comment
  1625. //              5/10/91   BryanW      Wrote it.
  1626. //
  1627. //---------------------------------------------------------------------------
  1628.  
  1629. BOOL NEAR WriteCommByte( HWND hWnd, BYTE bByte )
  1630. {
  1631. #ifdef WIN32
  1632.    BOOL        fWriteStat ;
  1633.    DWORD       dwBytesWritten ;
  1634. #endif
  1635.    NPTTYINFO  npTTYInfo ;
  1636.  
  1637.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1638.       return ( FALSE ) ;
  1639.  
  1640. #ifdef WIN32
  1641.    fWriteStat = WriteFile( COMDEV( npTTYInfo ), (LPSTR) &bByte, 1,
  1642.                            &dwBytesWritten, &WRITE_OS( npTTYInfo ) ) ;
  1643.    if (!fWriteStat && (GetLastError() == ERROR_IO_PENDING))
  1644.    {
  1645.       // wait for a second for this transmission to complete
  1646.  
  1647.       if (WaitForSingleObject( WRITE_OS( npTTYInfo ).hEvent, 1000 ))
  1648.          dwBytesWritten = 0 ;
  1649.       else
  1650.       {
  1651.          GetOverlappedResult( COMDEV( npTTYInfo ),
  1652.                               &WRITE_OS( npTTYInfo ),
  1653.                               &dwBytesWritten, FALSE ) ;
  1654.          WRITE_OS( npTTYInfo ).Offset += dwBytesWritten ;
  1655.       }
  1656.    }
  1657. #else
  1658.    WriteComm( COMDEV( npTTYInfo ), (LPSTR) &bByte, 1 ) ;
  1659. #endif
  1660.    return ( TRUE ) ;
  1661.  
  1662. } // end of WriteCommByte()
  1663.  
  1664. //---------------------------------------------------------------------------
  1665. //  BOOL NEAR WriteTTYBlock( HWND hWnd, LPSTR lpBlock, int nLength )
  1666. //
  1667. //  Description:
  1668. //     Writes block to TTY screen.  Nothing fancy - just
  1669. //     straight TTY.
  1670. //
  1671. //  Parameters:
  1672. //     HWND hWnd
  1673. //        handle to TTY window
  1674. //
  1675. //     LPSTR lpBlock
  1676. //        far pointer to block of data
  1677. //
  1678. //     int nLength
  1679. //        length of block
  1680. //
  1681. //  History:   Date       Author      Comment
  1682. //              5/ 9/91   BryanW      Wrote it.
  1683. //              5/20/91   BryanW      Modified... not character based,
  1684. //                                    block based now.  It was processing
  1685. //                                    per char.
  1686. //
  1687. //---------------------------------------------------------------------------
  1688.  
  1689. BOOL NEAR WriteTTYBlock( HWND hWnd, LPSTR lpBlock, int nLength )
  1690. {
  1691.    int        i ;
  1692.    NPTTYINFO  npTTYInfo ;
  1693.    RECT       rect ;
  1694.  
  1695.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1696.       return ( FALSE ) ;
  1697.  
  1698.    for (i = 0 ; i < nLength; i++)
  1699.    {
  1700.       switch (lpBlock[ i ])
  1701.       {
  1702.          case ASCII_BEL:
  1703.             // Bell
  1704.             MessageBeep( 0 ) ;
  1705.             break ;
  1706.    
  1707.          case ASCII_BS:
  1708.             // Backspace
  1709.             if (COLUMN( npTTYInfo ) > 0)
  1710.                COLUMN( npTTYInfo ) -- ;
  1711.             MoveTTYCursor( hWnd ) ;
  1712.             break ;
  1713.    
  1714.          case ASCII_CR:
  1715.             // Carriage return
  1716.             COLUMN( npTTYInfo ) = 0 ;
  1717.             MoveTTYCursor( hWnd ) ;
  1718.             if (!NEWLINE( npTTYInfo ))
  1719.                break;
  1720.    
  1721.             // fall through
  1722.    
  1723.          case ASCII_LF:
  1724.             // Line feed
  1725.             if (ROW( npTTYInfo )++ == MAXROWS - 1)
  1726.             {
  1727.                _fmemmove( (LPSTR) (SCREEN( npTTYInfo )),
  1728.                           (LPSTR) (SCREEN( npTTYInfo ) + MAXCOLS),
  1729.                           (MAXROWS - 1) * MAXCOLS ) ;
  1730.                _fmemset( (LPSTR) (SCREEN( npTTYInfo ) + (MAXROWS - 1) * MAXCOLS),
  1731.                          ' ', MAXCOLS ) ;
  1732.                InvalidateRect( hWnd, NULL, FALSE ) ;
  1733.                ROW( npTTYInfo )-- ;
  1734.             }
  1735.             MoveTTYCursor( hWnd ) ;
  1736.             break ;
  1737.  
  1738.          default:
  1739.             *(SCREEN( npTTYInfo ) + ROW( npTTYInfo ) * MAXCOLS +
  1740.                 COLUMN( npTTYInfo )) = lpBlock[ i ] ;
  1741.             rect.left = (COLUMN( npTTYInfo ) * XCHAR( npTTYInfo )) -
  1742.                         XOFFSET( npTTYInfo ) ;
  1743.             rect.right = rect.left + XCHAR( npTTYInfo ) ;
  1744.             rect.top = (ROW( npTTYInfo ) * YCHAR( npTTYInfo )) -
  1745.                        YOFFSET( npTTYInfo ) ;
  1746.             rect.bottom = rect.top + YCHAR( npTTYInfo ) ;
  1747.             InvalidateRect( hWnd, &rect, FALSE ) ;
  1748.  
  1749.             // Line wrap
  1750.             if (COLUMN( npTTYInfo ) < MAXCOLS - 1)
  1751.                COLUMN( npTTYInfo )++ ;
  1752.             else if (AUTOWRAP( npTTYInfo ))
  1753.                WriteTTYBlock( hWnd, "\r\n", 2 ) ;
  1754.             break;
  1755.       }
  1756.    }
  1757.    return ( TRUE ) ;
  1758.  
  1759. } // end of WriteTTYBlock()
  1760.  
  1761. //---------------------------------------------------------------------------
  1762. //  VOID NEAR GoModalDialogBoxParam( HINSTANCE hInstance,
  1763. //                                   LPCSTR lpszTemplate, HWND hWnd,
  1764. //                                   DLGPROC lpDlgProc, LPARAM lParam )
  1765. //
  1766. //  Description:
  1767. //     It is a simple utility function that simply performs the
  1768. //     MPI and invokes the dialog box with a DWORD paramter.
  1769. //
  1770. //  Parameters:
  1771. //     similar to that of DialogBoxParam() with the exception
  1772. //     that the lpDlgProc is not a procedure instance
  1773. //
  1774. //  History:   Date       Author      Comment
  1775. //              5/10/91   BryanW      Wrote it.
  1776. //
  1777. //---------------------------------------------------------------------------
  1778.  
  1779. VOID NEAR GoModalDialogBoxParam( HINSTANCE hInstance, LPCSTR lpszTemplate,
  1780.                                  HWND hWnd, DLGPROC lpDlgProc, LPARAM lParam )
  1781. {
  1782.    DLGPROC  lpProcInstance ;
  1783.  
  1784.    lpProcInstance = (DLGPROC) MakeProcInstance( (FARPROC) lpDlgProc,
  1785.                                                 hInstance ) ;
  1786.    DialogBoxParam( hInstance, lpszTemplate, hWnd, lpProcInstance, lParam ) ;
  1787.    FreeProcInstance( (FARPROC) lpProcInstance ) ;
  1788.  
  1789. } // end of GoModalDialogBoxParam()
  1790.  
  1791. //---------------------------------------------------------------------------
  1792. //  BOOL FAR PASCAL AboutDlgProc( HWND hDlg, UINT uMsg,
  1793. //                                WPARAM wParam, LPARAM lParam )
  1794. //
  1795. //  Description:
  1796. //     Simulates the Windows System Dialog Box.
  1797. //
  1798. //  Parameters:
  1799. //     Same as standard dialog procedures.
  1800. //
  1801. //  History:   Date       Author      Comment
  1802. //             10/19/91   BryanW      Added this little extra.
  1803. //      
  1804. //---------------------------------------------------------------------------
  1805.  
  1806. BOOL FAR PASCAL AboutDlgProc( HWND hDlg, UINT uMsg,
  1807.                               WPARAM wParam, LPARAM lParam )
  1808. {
  1809.    switch (uMsg)
  1810.    {
  1811.       case WM_INITDIALOG:
  1812.       {
  1813. #ifdef WIN32
  1814.          char         szBuffer[ MAXLEN_TEMPSTR ], szTemp[ MAXLEN_TEMPSTR ];
  1815.          WORD         wRevision, wVersion ;
  1816. #else
  1817.          int          idModeString ;
  1818.          char         szBuffer[ MAXLEN_TEMPSTR ], szTemp[ MAXLEN_TEMPSTR ] ;
  1819.          DWORD        dwFreeMemory, dwWinFlags ;
  1820.          WORD         wFreeResources, wRevision, wVersion ;
  1821. #endif
  1822.  
  1823. #ifdef ABOUTDLG_USEBITMAP
  1824.          // if we are using the bitmap, hide the icon
  1825.  
  1826.          ShowWindow( GetDlgItem( hDlg, IDD_ABOUTICON ), SW_HIDE ) ;
  1827. #endif
  1828.          // sets up the version number for Windows
  1829.  
  1830.          wVersion = LOWORD( GetVersion() ) ;
  1831.          wRevision = HIBYTE( wVersion ) ;
  1832.          wVersion = LOBYTE( wVersion ) ;
  1833.  
  1834.          GetDlgItemText( hDlg, IDD_TITLELINE, szTemp, sizeof( szTemp ) ) ;
  1835.          wsprintf( szBuffer, szTemp, wVersion, wRevision ) ;
  1836.          SetDlgItemText( hDlg, IDD_TITLELINE, szBuffer ) ;
  1837.  
  1838.          // sets up version number for TTY
  1839.  
  1840.          GetDlgItemText( hDlg, IDD_VERSION, szTemp, sizeof( szTemp ) ) ;
  1841.          wsprintf( szBuffer, szTemp, VER_MAJOR, VER_MINOR, VER_BUILD ) ;
  1842.          SetDlgItemText( hDlg, IDD_VERSION, (LPSTR) szBuffer ) ;
  1843.  
  1844.          // get by-line
  1845.  
  1846.          LoadString( GETHINST( hDlg ), IDS_BYLINE, szBuffer,
  1847.                      sizeof( szBuffer ) ) ;
  1848.          SetDlgItemText( hDlg, IDD_BYLINE, szBuffer ) ;
  1849.  
  1850. #ifndef WIN32
  1851.          // set windows mode information
  1852.  
  1853.          dwWinFlags = GetWinFlags() ;
  1854.          if (dwWinFlags & WF_ENHANCED)
  1855.             idModeString = IDS_MODE_ENHANCED ;
  1856.          else if (dwWinFlags & WF_STANDARD)
  1857.             idModeString = IDS_MODE_STANDARD ;
  1858.          else if (dwWinFlags & WF_WLO)
  1859.             idModeString = IDS_MODE_WLO ;
  1860.          else
  1861.             idModeString = IDS_MODE_UNDEF ;
  1862.  
  1863.          LoadString( GETHINST( hDlg ), idModeString, szBuffer,
  1864.                      sizeof( szBuffer ) ) ;
  1865.          SetDlgItemText( hDlg, IDD_WINDOWSMODE, szBuffer ) ;
  1866. #else
  1867.          SetDlgItemText( hDlg, IDD_WINDOWSMODE, "NT Mode" ) ;
  1868. #endif
  1869.  
  1870. #ifndef WIN32
  1871.          // get free memory information
  1872.  
  1873.          dwFreeMemory = GetFreeSpace( 0 ) / 1024L ;
  1874.          GetDlgItemText( hDlg, IDD_FREEMEM, szTemp, sizeof( szTemp ) ) ;
  1875.          wsprintf( szBuffer, szTemp, dwFreeMemory ) ;
  1876.          SetDlgItemText( hDlg, IDD_FREEMEM, (LPSTR) szBuffer ) ;
  1877.  
  1878.          // get free resources information
  1879.  
  1880.          wFreeResources = GetFreeSystemResources( 0 ) ;
  1881.          GetDlgItemText( hDlg, IDD_RESOURCES, szTemp, sizeof( szTemp ) ) ;
  1882.          wsprintf( szBuffer, szTemp, wFreeResources ) ;
  1883.          SetDlgItemText( hDlg, IDD_RESOURCES, (LPSTR) szBuffer ) ;
  1884. #endif
  1885.       }
  1886.       return ( TRUE ) ;
  1887.  
  1888. #ifdef ABOUTDLG_USEBITMAP
  1889.       // used to paint the bitmap
  1890.  
  1891.       case WM_PAINT:
  1892.       {
  1893.          HBITMAP      hBitMap ;
  1894.          HDC          hDC, hMemDC ;
  1895.          PAINTSTRUCT  ps ;
  1896.  
  1897.          // load bitmap and display it
  1898.  
  1899.          hDC = BeginPaint( hDlg, &ps ) ;
  1900.          if (NULL != (hMemDC = CreateCompatibleDC( hDC )))
  1901.          {
  1902.             hBitMap = LoadBitmap( GETHINST( hDlg ),
  1903.                                   MAKEINTRESOURCE( TTYBITMAP ) ) ;
  1904.             hBitMap = SelectObject( hMemDC, hBitMap ) ;
  1905.             BitBlt( hDC, 10, 10, 64, 64, hMemDC, 0, 0, SRCCOPY ) ;
  1906.             DeleteObject( SelectObject( hMemDC, hBitMap ) ) ;
  1907.             DeleteDC( hMemDC ) ;
  1908.          }
  1909.          EndPaint( hDlg, &ps ) ;
  1910.       }
  1911.       break ;
  1912. #endif
  1913.  
  1914.       case WM_COMMAND:
  1915.          if (LOWORD( wParam ) == IDD_OK)
  1916.          {
  1917.             EndDialog( hDlg, TRUE ) ;
  1918.             return ( TRUE ) ;
  1919.          }
  1920.          break;
  1921.    }
  1922.    return ( FALSE ) ;
  1923.  
  1924. } // end of AboutDlgProc()
  1925.  
  1926. //---------------------------------------------------------------------------
  1927. //  VOID NEAR FillComboBox( HINSTANCE hInstance, HWND hCtrlWnd, int nIDString,
  1928. //                          WORD NEAR *npTable, WORD wTableLen,
  1929. //                          WORD wCurrentSetting )
  1930. //
  1931. //  Description:
  1932. //     Fills the given combo box with strings from the resource
  1933. //     table starting at nIDString.  Associated items are
  1934. //     added from given table.  The combo box is notified of
  1935. //     the current setting.
  1936. //
  1937. //  Parameters:
  1938. //     HINSTANCE hInstance
  1939. //        handle to application instance
  1940. //
  1941. //     HWND hCtrlWnd
  1942. //        handle to combo box control
  1943. //
  1944. //     int nIDString
  1945. //        first resource string id
  1946. //
  1947. //     DWORD NEAR *npTable
  1948. //        near point to table of associated values
  1949. //
  1950. //     WORD wTableLen
  1951. //        length of table
  1952. //
  1953. //     DWORD dwCurrentSetting
  1954. //        current setting (for combo box selection)
  1955. //
  1956. //  History:   Date       Author      Comment
  1957. //             10/20/91   BryanW      Pulled from the init procedure.
  1958. //
  1959. //---------------------------------------------------------------------------
  1960.  
  1961. VOID NEAR FillComboBox( HINSTANCE hInstance, HWND hCtrlWnd, int nIDString,
  1962.                         DWORD NEAR *npTable, WORD wTableLen,
  1963.                         DWORD dwCurrentSetting )
  1964. {
  1965.    char  szBuffer[ MAXLEN_TEMPSTR ] ;
  1966.    WORD  wCount, wPosition ;
  1967.  
  1968.    for (wCount = 0; wCount < wTableLen; wCount++)
  1969.    {
  1970.       // load the string from the string resources and
  1971.       // add it to the combo box
  1972.  
  1973.       LoadString( hInstance, nIDString + wCount, szBuffer, sizeof( szBuffer ) ) ;
  1974.       wPosition = LOWORD( SendMessage( hCtrlWnd, CB_ADDSTRING, NULL,
  1975.                                        (LPARAM) (LPSTR) szBuffer ) ) ;
  1976.  
  1977.       // use item data to store the actual table value
  1978.  
  1979.       SendMessage( hCtrlWnd, CB_SETITEMDATA, (WPARAM) wPosition,
  1980.                    (LPARAM) *(npTable + wCount) ) ;
  1981.  
  1982.       // if this is our current setting, select it
  1983.  
  1984.       if (*(npTable + wCount) == dwCurrentSetting)
  1985.          SendMessage( hCtrlWnd, CB_SETCURSEL, (WPARAM) wPosition, NULL ) ;
  1986.    }
  1987.  
  1988. } // end of FillComboBox()
  1989.  
  1990. //---------------------------------------------------------------------------
  1991. //  BOOL NEAR SettingsDlgInit( HWND hDlg )
  1992. //
  1993. //  Description:
  1994. //     Puts current settings into dialog box (via CheckRadioButton() etc.)
  1995. //
  1996. //  Parameters:
  1997. //     HWND hDlg
  1998. //        handle to dialog box
  1999. //
  2000. //  Win-32 Porting Issues:
  2001. //     - Constants require DWORD arrays for baud rate table, etc.
  2002. //     - There is no "MAXCOM" function in Win-32.  Number of COM ports
  2003. //       is assumed to be 4.
  2004. //
  2005. //  History:   Date       Author      Comment
  2006. //              5/11/91   BryanW      Wrote it.
  2007. //             10/20/91   BryanW      Dialog revision.
  2008. //             10/24/91   BryanW      Fixed bug with EscapeCommFunction().
  2009. //              6/15/92   BryanW      Ported to Win-32.
  2010. //
  2011. //---------------------------------------------------------------------------
  2012.  
  2013. BOOL NEAR SettingsDlgInit( HWND hDlg )
  2014. {
  2015.    char       szBuffer[ MAXLEN_TEMPSTR ], szTemp[ MAXLEN_TEMPSTR ] ;
  2016.    NPTTYINFO  npTTYInfo ;
  2017.    WORD       wCount, wMaxCOM, wPosition ;
  2018.  
  2019.    if (NULL == (npTTYInfo = (NPTTYINFO) GET_PROP( hDlg, ATOM_TTYINFO )))
  2020.       return ( FALSE ) ;
  2021.  
  2022. #ifdef WIN32
  2023.    wMaxCOM = MAXPORTS ;
  2024. #else
  2025.    wMaxCOM = LOWORD( EscapeCommFunction( NULL, GETMAXCOM ) ) + 1 ;
  2026. #endif
  2027.  
  2028.    // load the COM prefix from resources
  2029.  
  2030.    LoadString( GETHINST( hDlg ), IDS_COMPREFIX, szTemp, sizeof( szTemp ) ) ;
  2031.  
  2032.    // fill port combo box and make initial selection
  2033.  
  2034.    for (wCount = 0; wCount < wMaxCOM; wCount++)
  2035.    {
  2036.       wsprintf( szBuffer, "%s%d", (LPSTR) szTemp, wCount + 1 ) ;
  2037.       SendDlgItemMessage( hDlg, IDD_PORTCB, CB_ADDSTRING, NULL,
  2038.                           (LPARAM) (LPSTR) szBuffer ) ;
  2039.    }
  2040.  
  2041. #ifdef WIN32 
  2042.    SendDlgItemMessage( hDlg, IDD_PORTCB, CB_ADDSTRING, NULL,
  2043.                        (LPARAM) (LPSTR) "TELNET" ) ;
  2044. #endif
  2045.    SendDlgItemMessage( hDlg, IDD_PORTCB, CB_SETCURSEL,
  2046.                        (WPARAM) (PORT( npTTYInfo ) - 1), NULL ) ;
  2047.  
  2048.    // disable COM port combo box if connection has already been
  2049.    // established (e.g. OpenComm() already successful)
  2050.  
  2051.    EnableWindow( GetDlgItem( hDlg, IDD_PORTCB ), !CONNECTED( npTTYInfo ) ) ;
  2052.  
  2053.    // fill baud combo box and make initial selection
  2054.  
  2055.    FillComboBox( GETHINST( hDlg ), GetDlgItem( hDlg, IDD_BAUDCB ),
  2056.                  IDS_BAUD110, BaudTable,
  2057.                  sizeof( BaudTable ) / sizeof( BaudTable[ 0 ] ),
  2058.                  BAUDRATE( npTTYInfo ) ) ;
  2059.  
  2060.    // fill data bits combo box and make initial selection
  2061.  
  2062.    for (wCount = 5; wCount < 9; wCount++)
  2063.    {
  2064.       wsprintf( szBuffer, "%d", wCount ) ;
  2065.       wPosition = LOWORD( SendDlgItemMessage( hDlg, IDD_DATABITSCB,
  2066.                                               CB_ADDSTRING, NULL,
  2067.                                               (LPARAM) (LPSTR) szBuffer ) ) ;
  2068.  
  2069.       // if current selection, tell the combo box
  2070.  
  2071.       if (wCount == BYTESIZE( npTTYInfo ))
  2072.          SendDlgItemMessage( hDlg, IDD_DATABITSCB, CB_SETCURSEL,
  2073.                              (WPARAM) wPosition, NULL ) ;
  2074.    }
  2075.  
  2076.    // fill parity combo box and make initial selection
  2077.  
  2078.    FillComboBox( GETHINST( hDlg ), GetDlgItem( hDlg, IDD_PARITYCB ),
  2079.                  IDS_PARITYNONE, ParityTable,
  2080.                  sizeof( ParityTable ) / sizeof( ParityTable[ 0 ] ),
  2081.                  PARITY( npTTYInfo ) ) ;
  2082.  
  2083.    // fill stop bits combo box and make initial selection
  2084.  
  2085.    FillComboBox( GETHINST( hDlg ), GetDlgItem( hDlg, IDD_STOPBITSCB ),
  2086.                  IDS_ONESTOPBIT, StopBitsTable,
  2087.                  sizeof( StopBitsTable ) / sizeof ( StopBitsTable ),
  2088.                  STOPBITS( npTTYInfo ) ) ;
  2089.  
  2090.    // initalize the flow control settings
  2091.  
  2092.    CheckDlgButton( hDlg, IDD_DTRDSR,
  2093.                    (FLOWCTRL( npTTYInfo ) & FC_DTRDSR) > 0 ) ;
  2094.    CheckDlgButton( hDlg, IDD_RTSCTS,
  2095.                    (FLOWCTRL( npTTYInfo ) & FC_RTSCTS) > 0 ) ;
  2096.    CheckDlgButton( hDlg, IDD_XONXOFF,
  2097.                    (FLOWCTRL( npTTYInfo ) & FC_XONXOFF) > 0 ) ;
  2098.  
  2099.    // other TTY settings
  2100.  
  2101.    CheckDlgButton( hDlg, IDD_AUTOWRAP, AUTOWRAP( npTTYInfo ) ) ;
  2102.    CheckDlgButton( hDlg, IDD_NEWLINE, NEWLINE( npTTYInfo ) ) ;
  2103.    CheckDlgButton( hDlg, IDD_LOCALECHO, LOCALECHO( npTTYInfo ) ) ;
  2104.  
  2105.    // control options
  2106.  
  2107. #ifdef WIN32
  2108.    // "Use CN_RECEIVE" is not valid under Win-32
  2109.  
  2110.    EnableWindow( GetDlgItem( hDlg, IDD_USECNRECEIVE ), FALSE ) ;
  2111. #else
  2112.    CheckDlgButton( hDlg, IDD_USECNRECEIVE, USECNRECEIVE( npTTYInfo ) ) ;
  2113.  
  2114.    // disable Use CN_RECEIVE option if connection has already been
  2115.    // established (e.g. OpenComm() already successful)
  2116.  
  2117.    EnableWindow( GetDlgItem( hDlg, IDD_USECNRECEIVE ),
  2118.                  !CONNECTED( npTTYInfo ) ) ;
  2119. #endif
  2120.  
  2121.    CheckDlgButton( hDlg, IDD_DISPLAYERRORS, DISPLAYERRORS( npTTYInfo ) ) ;
  2122.  
  2123.    return ( TRUE ) ;
  2124.  
  2125. } // end of SettingsDlgInit()
  2126.  
  2127. //---------------------------------------------------------------------------
  2128. //  BOOL NEAR SelectTTYFont( HWND hDlg )
  2129. //
  2130. //  Description:
  2131. //     Selects the current font for the TTY screen.
  2132. //     Uses the Common Dialog ChooseFont() API.
  2133. //
  2134. //  Parameters:
  2135. //     HWND hDlg
  2136. //        handle to settings dialog
  2137. //
  2138. //  History:   Date       Author      Comment
  2139. //             10/20/91   BryanW      Wrote it.
  2140. //
  2141. //---------------------------------------------------------------------------
  2142.  
  2143. BOOL NEAR SelectTTYFont( HWND hDlg )
  2144. {
  2145.    CHOOSEFONT  cfTTYFont ;
  2146.    NPTTYINFO   npTTYInfo ;
  2147.  
  2148.    if (NULL == (npTTYInfo = (NPTTYINFO) GET_PROP( hDlg, ATOM_TTYINFO )))
  2149.       return ( FALSE ) ;
  2150.  
  2151.    cfTTYFont.lStructSize    = sizeof( CHOOSEFONT ) ;
  2152.    cfTTYFont.hwndOwner      = hDlg ;
  2153.    cfTTYFont.hDC            = NULL ;
  2154.    cfTTYFont.rgbColors      = FGCOLOR( npTTYInfo ) ;
  2155.    cfTTYFont.lpLogFont      = &LFTTYFONT( npTTYInfo ) ;
  2156.    cfTTYFont.Flags          = CF_SCREENFONTS | CF_FIXEDPITCHONLY |
  2157.                               CF_EFFECTS | CF_INITTOLOGFONTSTRUCT ;
  2158.    cfTTYFont.lCustData      = NULL ;
  2159.    cfTTYFont.lpfnHook       = NULL ;
  2160.    cfTTYFont.lpTemplateName = NULL ;
  2161.    cfTTYFont.hInstance      = GETHINST( hDlg ) ;
  2162.  
  2163.    if (ChooseFont( &cfTTYFont ))
  2164.    {
  2165.      FGCOLOR( npTTYInfo ) = cfTTYFont.rgbColors ;
  2166.      ResetTTYScreen( GetParent( hDlg ), npTTYInfo ) ;
  2167.    }
  2168.  
  2169.    return ( TRUE ) ;
  2170.  
  2171. } // end of SelectTTYFont()
  2172.  
  2173. //---------------------------------------------------------------------------
  2174. //  BOOL NEAR SettingsDlgTerm( HWND hDlg )
  2175. //
  2176. //  Description:
  2177. //     Puts dialog contents into TTY info structure.
  2178. //
  2179. //  Parameters:
  2180. //     HWND hDlg
  2181. //        handle to settings dialog
  2182. //
  2183. //  Win-32 Porting Issues:
  2184. //     - Baud rate requires DWORD values.
  2185. //
  2186. //  History:   Date       Author      Comment
  2187. //              5/11/91   BryanW      Wrote it.
  2188. //              6/15/92   BryanW      Ported to Win-32.
  2189. //
  2190. //---------------------------------------------------------------------------
  2191.  
  2192. BOOL NEAR SettingsDlgTerm( HWND hDlg )
  2193. {
  2194.    NPTTYINFO  npTTYInfo ;
  2195.    WORD       wSelection ;
  2196.  
  2197.    if (NULL == (npTTYInfo = (NPTTYINFO) GET_PROP( hDlg, ATOM_TTYINFO )))
  2198.       return ( FALSE ) ;
  2199.  
  2200.    // get port selection
  2201.  
  2202.    PORT( npTTYInfo ) =
  2203.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_PORTCB,
  2204.                                           CB_GETCURSEL,
  2205.                                           NULL, NULL ) ) + 1 ) ;
  2206.    // get baud rate selection
  2207.  
  2208.    wSelection =
  2209.       LOWORD( SendDlgItemMessage( hDlg, IDD_BAUDCB, CB_GETCURSEL,
  2210.                                   NULL, NULL ) ) ;
  2211. #ifdef WIN32
  2212.    BAUDRATE( npTTYInfo ) =
  2213.       SendDlgItemMessage( hDlg, IDD_BAUDCB, CB_GETITEMDATA,
  2214.                           (WPARAM) wSelection, NULL ) ;
  2215. #else
  2216.    BAUDRATE( npTTYInfo ) =
  2217.       LOWORD( SendDlgItemMessage( hDlg, IDD_BAUDCB, CB_GETITEMDATA,
  2218.                                   (WPARAM) wSelection, NULL ) ) ;
  2219. #endif
  2220.  
  2221.    // get data bits selection
  2222.  
  2223.    BYTESIZE( npTTYInfo ) =
  2224.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_DATABITSCB,
  2225.                                           CB_GETCURSEL,
  2226.                                           NULL, NULL ) ) + 5 ) ;
  2227.  
  2228.    // get parity selection
  2229.  
  2230.    wSelection =
  2231.       LOWORD( SendDlgItemMessage( hDlg, IDD_PARITYCB, CB_GETCURSEL,
  2232.                                   NULL, NULL ) ) ;
  2233.    PARITY( npTTYInfo ) =
  2234.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_PARITYCB,
  2235.                                           CB_GETITEMDATA,
  2236.                                           (WPARAM) wSelection,
  2237.                                            NULL ) ) ) ;
  2238.  
  2239.    // get stop bits selection
  2240.  
  2241.    wSelection =
  2242.       LOWORD( SendDlgItemMessage( hDlg, IDD_STOPBITSCB, CB_GETCURSEL,
  2243.                                   NULL, NULL ) ) ;
  2244.    STOPBITS( npTTYInfo ) =
  2245.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_STOPBITSCB,
  2246.                                           CB_GETITEMDATA,
  2247.                                           (WPARAM) wSelection, NULL ) ) ) ;
  2248.  
  2249.    // get flow control settings
  2250.  
  2251.    FLOWCTRL( npTTYInfo ) = 0 ;
  2252.    if (IsDlgButtonChecked( hDlg, IDD_DTRDSR ))
  2253.       FLOWCTRL( npTTYInfo ) |= FC_DTRDSR ;
  2254.    if (IsDlgButtonChecked( hDlg, IDD_RTSCTS ))
  2255.       FLOWCTRL( npTTYInfo ) |= FC_RTSCTS ;
  2256.    if (IsDlgButtonChecked( hDlg, IDD_XONXOFF ))
  2257.       FLOWCTRL( npTTYInfo ) |= FC_XONXOFF ;
  2258.  
  2259.    // get other various settings
  2260.  
  2261.    AUTOWRAP( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_AUTOWRAP ) ;
  2262.    NEWLINE( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_NEWLINE ) ;
  2263.    LOCALECHO( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_LOCALECHO ) ;
  2264.  
  2265.    // control options
  2266.  
  2267.    USECNRECEIVE( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_USECNRECEIVE ) ;
  2268.    DISPLAYERRORS( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_DISPLAYERRORS ) ;
  2269.  
  2270.    return ( TRUE ) ;
  2271.  
  2272. } // end of SettingsDlgTerm()
  2273.  
  2274. //---------------------------------------------------------------------------
  2275. //  BOOL FAR PASCAL SettingsDlgProc( HWND hDlg, UINT uMsg,
  2276. //                                   WPARAM wParam, LPARAM lParam )
  2277. //
  2278. //  Description:
  2279. //     This handles all of the user preference settings for
  2280. //     the TTY.
  2281. //
  2282. //  Parameters:
  2283. //     same as all dialog procedures
  2284. //
  2285. //  Win-32 Porting Issues:
  2286. //     - npTTYInfo is a DWORD in Win-32.
  2287. //
  2288. //  History:   Date       Author      Comment
  2289. //              5/10/91   BryanW      Wrote it.
  2290. //             10/20/91   BryanW      Now uses window properties to
  2291. //                                    store TTYInfo handle.  Also added
  2292. //                                    font selection.
  2293. //              6/15/92   BryanW      Ported to Win-32.
  2294. //
  2295. //---------------------------------------------------------------------------
  2296.  
  2297. BOOL FAR PASCAL SettingsDlgProc( HWND hDlg, UINT uMsg,
  2298.                                  WPARAM wParam, LPARAM lParam )
  2299. {
  2300.    switch (uMsg)
  2301.    {
  2302.       case WM_INITDIALOG:
  2303.       {
  2304.          NPTTYINFO  npTTYInfo ;
  2305.  
  2306.          // get & save pointer to TTY info structure
  2307.  
  2308. #ifdef WIN32
  2309.          npTTYInfo = (NPTTYINFO) lParam ;
  2310. #else
  2311.          npTTYInfo = (NPTTYINFO) LOWORD( lParam ) ;
  2312. #endif
  2313.  
  2314.          SET_PROP( hDlg, ATOM_TTYINFO, (HANDLE) npTTYInfo ) ;
  2315.  
  2316.          return ( SettingsDlgInit( hDlg ) ) ;
  2317.       }
  2318.  
  2319.       case WM_COMMAND:
  2320.          switch ( LOWORD( wParam ))
  2321.          {
  2322.             case IDD_FONT:
  2323.                return ( SelectTTYFont( hDlg ) ) ;
  2324.  
  2325.             case IDD_OK:
  2326.                // Copy stuff into structure
  2327.                SettingsDlgTerm( hDlg ) ;
  2328.                EndDialog( hDlg, TRUE ) ;
  2329.                return ( TRUE ) ;
  2330.  
  2331.             case IDD_CANCEL:
  2332.                // Just end
  2333.                EndDialog( hDlg, TRUE ) ;
  2334.                return ( TRUE ) ;
  2335.          }
  2336.          break;
  2337.  
  2338.       case WM_DESTROY:
  2339.          REMOVE_PROP( hDlg, ATOM_TTYINFO ) ;
  2340.          break ;
  2341.    }
  2342.    return ( FALSE ) ;
  2343.  
  2344. } // end of SettingsDlgProc()
  2345.  
  2346. #ifdef WIN32
  2347.  
  2348. //************************************************************************
  2349. //  DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
  2350. //
  2351. //  Description:
  2352. //     A secondary thread that will watch for COMM events.
  2353. //
  2354. //  Parameters:
  2355. //     LPSTR lpData
  2356. //        32-bit pointer argument
  2357. //
  2358. //  Win-32 Porting Issues:
  2359. //     - Added this thread to watch the communications device and
  2360. //       post notifications to the associated window.
  2361. //
  2362. //  History:   Date       Author      Comment
  2363. //             12/31/91   BryanW      Wrote it.
  2364. //              6/12/92   BryanW      CommWaitEvent() now uses
  2365. //                                    an overlapped structure.
  2366. //
  2367. //************************************************************************
  2368.  
  2369. DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
  2370. {
  2371.    DWORD       dwTransfer, dwEvtMask ;
  2372.    NPTTYINFO   npTTYInfo = (NPTTYINFO) lpData ;
  2373.    OVERLAPPED  os ;
  2374.  
  2375.    memset( &os, 0, sizeof( OVERLAPPED ) ) ;
  2376.  
  2377.    // create I/O event used for overlapped read
  2378.  
  2379.    os.hEvent = CreateEvent( NULL,    // no security
  2380.                             TRUE,    // explicit reset req
  2381.                             FALSE,   // initial event reset
  2382.                             NULL ) ; // no name
  2383.    if (os.hEvent == NULL)
  2384.    {
  2385.       MessageBox( NULL, "Failed to create event for thread!", "TTY Error!",
  2386.                   MB_ICONEXCLAMATION | MB_OK ) ;
  2387.       return ( FALSE ) ;
  2388.    }
  2389.  
  2390.    if (!SetCommMask( COMDEV( npTTYInfo ), EV_RXCHAR ))
  2391.       return ( FALSE ) ;
  2392.  
  2393.    while ( CONNECTED( npTTYInfo ) )
  2394.    {
  2395.       dwEvtMask = NULL ;
  2396.  
  2397.       if (!WaitCommEvent( COMDEV( npTTYInfo ), &dwEvtMask, &os ))
  2398.       {
  2399.          if (ERROR_IO_PENDING == GetLastError())
  2400.          {
  2401.             GetOverlappedResult( COMDEV( npTTYInfo ), &os, &dwTransfer, TRUE ) ;
  2402.             os.Offset += dwTransfer ;
  2403.          }
  2404.       }
  2405.  
  2406.       if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
  2407.       {
  2408.          // wait for "posted notification" flag to clear
  2409.  
  2410.          WaitForSingleObject( POSTEVENT( npTTYInfo ), 0xFFFFFFFF ) ;
  2411.  
  2412.          // reset event
  2413.  
  2414.          ResetEvent( POSTEVENT( npTTYInfo ) ) ;
  2415.  
  2416.          // last message was processed, O.K. to post
  2417.  
  2418.          PostMessage( TERMWND( npTTYInfo ), WM_COMMNOTIFY,
  2419.                       (WPARAM) COMDEV( npTTYInfo ),
  2420.                       MAKELONG( CN_EVENT, 0 ) ) ;
  2421.       }
  2422.    }
  2423.  
  2424.    // get rid of event handle
  2425.  
  2426.    CloseHandle( os.hEvent ) ;
  2427.  
  2428.    // clear information in structure (kind of a "we're done flag")
  2429.  
  2430.    THREADID( npTTYInfo ) = NULL ;
  2431.    HTHREAD( npTTYInfo ) = NULL ;
  2432.  
  2433.    return( TRUE ) ;
  2434.  
  2435. } // end of CommWatchProc()
  2436.  
  2437. #endif
  2438.  
  2439. //---------------------------------------------------------------------------
  2440. //  End of File: tty.c
  2441. //---------------------------------------------------------------------------
  2442.